[英]Removing tuples from a list
我正在嘗試從列表中刪除一個元組。 如果列表中的第一個元素等於“ -NONE-”,我想刪除整個元組。 嘗試其他操作時,我總是會出錯。 這是我所擁有的:
def filter(sent):
for tuple in sent:
if tuple[1] == "-NONE-":
sent.remove(sent.index(tuple))
我正在使用此測試來調用方法:
filter([('uh', 'UH'), ('i', 'PRP'), ('think', 'VBP'), (',', ','), ('*0*', '-NONE-'), ('it', 'PRP'), ("'s", 'BES'), ('because', 'IN'), ('i', 'PRP'), ('get', 'VBP'), ('*', '-NONE-'), ('to', 'TO'), ('be', 'VB'), ('something', 'NN'), ('that', 'WDT'), ('i', 'PRP'), ("'m", 'VBP'), ('not', 'RB'), ('*T*', '-NONE-'), ('.', '.')])
但我不斷收到此錯誤:
Traceback (most recent call last):
File "<pyshell#273>", line 1, in <module>
filter([('uh', 'UH'), ('i', 'PRP'), ('think', 'VBP'), (',', ','), ('*0*', '-NONE-'), ('it', 'PRP'), ("'s", 'BES'), ('because', 'IN'), ('i', 'PRP'), ('get', 'VBP'), ('*', '-NONE-'), ('to', 'TO'), ('be', 'VB'), ('something', 'NN'), ('that', 'WDT'), ('i', 'PRP'), ("'m", 'VBP'), ('not', 'RB'), ('*T*', '-NONE-'), ('.', '.')])
File "<pyshell#272>", line 4, in filter
sent.remove(sent.index(tuple))
ValueError: list.remove(x): x not in list
remove
方法從列表中刪除一個對象,而不是一個索引。 您可以使用不帶索引的del
,也可以通過元組直接remove
:
def filter(sent):
for tuple in sent:
if tuple[1] == "-NONE-":
# del sent[sent.index(tuple)]
sent.remove(tuple)
但是,這仍然行不通。 您在迭代列表的同時對其進行了修改,這將增加您在迭代中的位置。 同樣, index
和remove
都很慢,並且命名一個函數filter
,隱藏內置filter
功能是一個壞主意。 最好使用列表理解來創建一個新的過濾列表:
def filtered(sent):
return [item for item in sent if item[1] != "-NONE-"]
您需要做的就是
sent.remove(tuple)
如果您絕對想找到索引,則需要使用pop
,如下所示:
sent.pop(sent.index(tuple))
Remove在列表中找到該對象,然后將其刪除(但前提是該對象存在)。 帶有索引的流行作品
如user2357112所述,您不應該從迭代的同一列表中刪除項目。 這無疑會引起您的頭痛。 他們的答案是更好的答案。
您的直接錯誤是list.remove
期望將項目作為其參數,而不是索引。 也就是說,您想使用sent.remove(tuple)
而不是sent.remove(sent.index(tuple))
。 或者,使用del
,它確實按索引刪除( del sent[sent.index(tuple)]
)。 但是,使用這些修復程序中的任何一個,您的算法仍然會遇到問題。
原因是要在從列表中刪除項目的同時對列表進行迭代。 通過內部使用索引來列出迭代,因此,當您刪除一項時,所有后續項都向上移動一個空格,而被刪除的項之后的下一項將被迭代跳過。
更好的方法通常是使用列表理解來過濾列表:
def filter(sent):
return [tuple for tuple in sent if tuple[1] != "-NONE-"]
請注意,這將返回一個新列表,而不是就地修改原始列表。 如果要在適當位置進行修改,則可以執行此操作,但是您需要反向遍歷列表,以使尚未檢查的值的索引不會更改。 盡管它們都有些丑陋,但這是一種可行的方法:
def filter(sent):
for i, val in enumerate(reversed(sent), 1): # iterate in reverse order
if val[1] == "-NONE-":
del sent[-i] # del operator removes items by index
不用定義自己的過濾器函數,而使用內置函數:
z = [('uh', 'UH'), ('i', 'PRP'), ('think', 'VBP'), (',', ','), ('*0*', '-NONE-'), ('it', 'PRP'), ("'s", 'BES'), ('because', 'IN'), ('i', 'PRP'), ('get', 'VBP'), ('*', '-NONE-'), ('to', 'TO'), ('be', 'VB'), ('something', 'NN'), ('that', 'WDT'), ('i', 'PRP'), ("'m", 'VBP'), ('not', 'RB'), ('*T*', '-NONE-'), ('.', '.')]
z_filtered = filter(lambda item: item[1] != '-NONE-', z)
或使用itertools.ifilter():
import itertools as it
filtered = list(it.ifilter(lambda item: item[1] != '-NONE-', z))
它們都比@Blckknght或@ user2357112的列表理解要慢一些。 這是有競爭力的:
def f(z):
for item in z:
if item[1] != '-NONE-':
yield item
filtered = list(f(z))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.