簡體   English   中英

從列表中刪除元組

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

但是,這仍然行不通。 您在迭代列表的同時對其進行了修改,這將增加您在迭代中的位置。 同樣, indexremove都很慢,並且命名一個函數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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM