我遇到的问题是在“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(“先看You Leap”,意思是你检查你是否能够做你想做的事)。
在这种情况下,这可能是真的。例如,您想将-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]