[英]Returning values from inside a loop
首先,我是一个python Noob。 我可能要问的可能是常识; 但是,我很难搞清楚它。 我正在尝试创建一个函数,该函数接收读入的CSV文件并更改列表中元素的类型。 例如,如果列表被读作['A','B','2']
,则在执行该函数后它将变为['A','B',2]
。 以下是我的代码:
def type_setter(x):
x = list(x)
for row in x:
for i in row:
if i.isdigit() == True:
i = eval(i)
return [row for row in x]
我遇到的问题是在if i.isdigit()==True:
part之后返回值。 似乎值保持在循环内并且不存储到列表x中。 任何帮助是极大的赞赏。
我遇到的问题是在“if i.isdigit()== True:”部分之后返回值。 似乎值保持在循环内并且不存储到列表x中。
那是因为你没有做任何事情来将它们存储在列表中。 只是做i = eval(i)
只是将局部变量i
重新分配给一个新值。
例如,您可以这样做:
for row in x:
for index, i in enumerate(row):
if i.isdigit() == True:
row[index] = eval(i)
在这里,我们将列表成员row[index]
重新分配给一个新值,这正是您想要做的。
一些旁注:
构建新列表通常要比尝试修改一个列表简单得多。
你应该几乎从不打电话给eval
。 如果要将数字转换为整数,只需使用int
。 (对于更高级的情况,你有某种Python文字,你可能需要ast.literal_eval
。但你永远不会想要eval
,除非你真的想要运行任意代码。)
你几乎不想检查== True
。
此外, [row for row in x]
与list(x)
完全相同 - 在这种情况下,它只是x
的额外副本,因为您已经将x
转换为列表。
如果你能找到一种方法来实现这一点,而不是两个,你不需要在顶部的x = list(x)
。
把它们放在一起:
def type_setter(x):
new_x = []
for row in x:
new_row = []
for i in row:
if i.isdigit():
new_row.append(int(i))
else:
new_row.append(i)
new_x.append(new_row)
return new_x
或者,更简洁:
def type_setter(x):
return [[int(i) if i.isdigit() else i] for i in row] for row in x]
虽然将它作为两个表达式而不是一个表达式可能更具可读性:
def type_setter(x):
def intify(i):
return int(i) if i.isdigit() else i
return [[intify(i) for i in row] for row in x]
最后一点,在Python中, EAFP (“更容易请求宽恕而非权限”,意味着你只是尝试你想做的事情,并在你不能做的时候处理错误)通常比LBYL更简单(“Look Before”你跳了“,意味着你检查你是否能够做你想做的事情。
在这种情况下可能也是如此。 例如,您想将-123
视为整数而不是字符串吗? 然后i.isdigit()
是错误的测试; 你需要更复杂的东西。 事实上,在这种情况下,你真正想要的测试是“是一个整数的字符串表示”,对吧? 这是一个很难在不调用int
情况下编写的测试。 所以只需称呼它:
def type_setter(x):
def intify(i):
try:
return int(i)
except ValueError:
return i
return [[intify(i) for i in row] for row in x]
您可以直接修改列表:
def type_setter(x):
x = list(x)
for row_num, row in enumerate(x):
for col_num, i in enumerate(row):
if i.isdigit() == True:
x[row_num][col_num] = int(i)
return x
此外,你不应该使用eval
评估任何不受信任来源。 在cour情况下,您可以使用int
将字符串转换为数字。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.