我在Python中迭代一个元组列表,并试图删除它们,如果它们满足某些条件。

for tup in somelist:
    if determine(tup):
         code_to_remove_tup

我应该用什么来代替code_to_remove_tup?我不知道怎么用这种方式把东西拿掉。


当前回答

一个可能的解决方案,如果你不仅想删除一些东西,而且还想对单个循环中的所有元素做一些事情,这个解决方案很有用:

alist = ['good', 'bad', 'good', 'bad', 'good']
i = 0
for x in alist[:]:
    if x == 'bad':
        alist.pop(i)
        i -= 1
    # do something cool with x or just print x
    print(x)
    i += 1

其他回答

如果希望在迭代时从列表中删除元素,请使用while循环,以便在每次删除后都可以更改当前索引和结束索引。

例子:

i = 0
length = len(list1)

while i < length:
    if condition:
        list1.remove(list1[i])
        i -= 1
        length -= 1

    i += 1

对于喜欢函数式编程的人:

somelist[:] = filter(lambda tup: not determine(tup), somelist)

or

from itertools import ifilterfalse
somelist[:] = list(ifilterfalse(determine, somelist))

如果您想在迭代期间做其他事情,那么最好同时获得索引(这保证您能够引用它,例如,如果您有一个字典列表)和实际的列表项内容。

inlist = [{'field1':10, 'field2':20}, {'field1':30, 'field2':15}]    
for idx, i in enumerate(inlist):
    do some stuff with i['field1']
    if somecondition:
        xlist.append(idx)
for i in reversed(xlist): del inlist[i]

Enumerate使您可以同时访问项和索引。反向是为了以后你要删除的索引不会改变。

您可以使用列表推导式创建一个新列表,其中只包含您不想删除的元素:

somelist = [x for x in somelist if not determine(x)]

或者,通过分配slice somlist[:],你可以改变现有的列表,只包含你想要的项:

somelist[:] = [x for x in somelist if not determine(x)]

如果对某个列表的其他引用需要反映更改,则此方法可能很有用。

你也可以使用itertools来代替理解函数。在Python 2中:

from itertools import ifilterfalse
somelist[:] = ifilterfalse(determine, somelist)

或者在python3中:

from itertools import filterfalse
somelist[:] = filterfalse(determine, somelist)

如果当前列表项满足所需的条件,那么创建一个新列表可能是聪明的做法。

so:

for item in originalList:
   if (item != badValue):
        newList.append(item)

为了避免用新的列表名称重新编码整个项目:

originalList[:] = newList

注意,来自Python文档:

copy.copy (x) 返回x的浅拷贝。 copy.deepcopy (x) 返回x的深拷贝。