我的代碼跳過了一些看起來像的字符串。爲什麼我的代碼會過濾掉所有的字符串?
def filter_list(l):
for i in l:
if type(i) == str:
l.remove(i)
return l
print filter_list([1, 2, 3, '4', '5', 6, '7', 8])
它輸出:
[1, 2, 3, '5', 6, 8]
跳過「5」串
我的代碼跳過了一些看起來像的字符串。爲什麼我的代碼會過濾掉所有的字符串?
def filter_list(l):
for i in l:
if type(i) == str:
l.remove(i)
return l
print filter_list([1, 2, 3, '4', '5', 6, '7', 8])
它輸出:
[1, 2, 3, '5', 6, 8]
跳過「5」串
在評論中提到:當你迭代它(你不應該改變一個列表,除非你真的知道你在做什麼)。
和isinstance
通常比使用比type
更安全。
與list-comprehension你可以這樣做:
def filter_list(l):
return [item for item in l if not isinstance(item, str)]
print(filter_list([1, 2, 3, '4', '5', 6, '7', 8])) # [1, 2, 3, 6, 8]
當執行流程在3
位置遇到的第一個字符串"4"
,刪除它,並改變所有剩餘項目的左邊,這樣"5"
將在指數3
。但是下一個循環迭代的位置是4
,所以它跳過了"5"
。
考慮使用filter()函數來執行適當的濾波處理中的以下方法:
def filter_list(l):
return list(filter(lambda i: not isinstance(i,str), l))
print filter_list([1, 2, 3, '4', '5', 6, '7', 8])
輸出:
[1, 2, 3, 6, 8]
卸下元素,而迭代,是緩慢和危險的。最好的選擇是創建一個新列表new_list = [x for x in l if not isinstance(x,str)]
。如果列表是非常大的,你可以先找到符合條件的所有元素之後將其刪除
strings = [i for i,x in enumerate(l) if isinstance(x,str)]
for x in reversed(strings):
del l[x]
所以第一選擇(最快):
def filter_list(l):
return [x for x in l if not isinstance(x, str)]
print(filter_list([1, 2, 3, '4', '5', 6, '7', 8]))
第二(如果數量的值刪除的很小,但是列表的大小很大):
def filter_list(l):
strings = [i for i, x in enumerate(l) if isinstance(x, str)]
for x in reversed(strings):
del l[x]
l = [1, 2, 3, '4', '5', 6, '7', 8]
filter_list(l)
print(l)
所以纔會 「code'def filter_list(1): 指數= [] 爲我在L: 如果類型(I)= STR: indices.append(I) 回報指數 '代碼' 工作更好? –
如何讓代碼在評論中以代碼格式發佈? –
@LoganPipes,編輯 – Sklert
您正在更改正在迭代的列表。這通常以眼淚結束。嘗試列表理解。 –