[英]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.