我在Python中迭代一个元组列表,并试图删除它们,如果它们满足某些条件。
for tup in somelist:
if determine(tup):
code_to_remove_tup
我应该用什么来代替code_to_remove_tup?我不知道怎么用这种方式把东西拿掉。
我在Python中迭代一个元组列表,并试图删除它们,如果它们满足某些条件。
for tup in somelist:
if determine(tup):
code_to_remove_tup
我应该用什么来代替code_to_remove_tup?我不知道怎么用这种方式把东西拿掉。
当前回答
建议列表推导的答案几乎是正确的,除了它们构建了一个全新的列表,然后给它一个与旧列表相同的名称,它们没有在适当的地方修改旧列表。这与Lennart建议的选择性删除不同——它更快,但如果您的列表是通过多个引用访问的,那么您只是重新设置了其中一个引用,而没有更改列表对象本身,这可能会导致微妙的、灾难性的错误。
幸运的是,它非常容易获得列表推导式的速度和所需的就地更改的语义——只是代码:
somelist[:] = [tup for tup in somelist if determine(tup)]
请注意与其他答案的细微区别:这个答案没有分配给一个裸名。它赋值给一个列表切片,恰好是整个列表,因此替换了同一Python列表对象中的列表内容,而不是像其他答案一样只是重新设置一个引用(从以前的列表对象到新的列表对象)。
其他回答
如果希望在迭代时从列表中删除元素,请使用while循环,以便在每次删除后都可以更改当前索引和结束索引。
例子:
i = 0
length = len(list1)
while i < length:
if condition:
list1.remove(list1[i])
i -= 1
length -= 1
i += 1
我需要做一些类似的事情,在我的情况下,问题是内存——我需要在一个列表中合并多个数据集对象,在对它们做了一些事情之后,作为一个新对象,并且需要摆脱我正在合并的每个条目,以避免重复所有它们并增加内存。在我的情况下,对象在一个字典而不是一个列表工作得很好:
```
k = range(5)
v = ['a','b','c','d','e']
d = {key:val for key,val in zip(k, v)}
print d
for i in range(5):
print d[i]
d.pop(i)
print d
```
您需要获取列表的副本并首先对其进行迭代,否则迭代将失败,可能会出现意想不到的结果。
例如(取决于列表的类型):
for tup in somelist[:]:
etc....
一个例子:
>>> somelist = range(10)
>>> for x in somelist:
... somelist.remove(x)
>>> somelist
[1, 3, 5, 7, 9]
>>> somelist = range(10)
>>> for x in somelist[:]:
... somelist.remove(x)
>>> somelist
[]
对于这样的示例,最好的方法是列表理解
somelist = [tup for tup in somelist if determine(tup)]
如果您要做的事情比调用确定函数更复杂,我更喜欢构造一个新列表,并在执行过程中简单地追加它。例如
newlist = []
for tup in somelist:
# lots of code here, possibly setting things up for calling determine
if determine(tup):
newlist.append(tup)
somelist = newlist
使用remove复制列表可能会使您的代码看起来更简洁,如下面的其中一个答案所述。对于非常大的列表,您绝对不应该这样做,因为这涉及到首先复制整个列表,并对被删除的每个元素执行O(n)删除操作,使其成为O(n^2)算法。
for tup in somelist[:]:
# lots of code here, possibly setting things up for calling determine
if determine(tup):
newlist.append(tup)
如果您想在迭代期间做其他事情,那么最好同时获得索引(这保证您能够引用它,例如,如果您有一个字典列表)和实际的列表项内容。
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使您可以同时访问项和索引。反向是为了以后你要删除的索引不会改变。