我在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列表对象中的列表内容,而不是像其他答案一样只是重新设置一个引用(从以前的列表对象到新的列表对象)。
其他回答
for i in range(len(somelist) - 1, -1, -1):
if some_condition(somelist, i):
del somelist[i]
你需要向后走,否则就有点像锯掉你坐着的树枝:-)
Python 2用户:用xrange替换range以避免创建硬编码的列表
for循环将遍历一个索引…
假设你有一个清单,
[5, 7, 13, 29, 65, 91]
您使用了一个名为lis的列表变量。你用同样的方法来移除…
你的变量
lis = [5, 7, 13, 29, 35, 65, 91]
0 1 2 3 4 5 6
在第5次迭代中,
你的数字35不是质数,所以你把它从列表中删除了。
lis.remove(y)
然后下一个值(65)移动到前一个索引。
lis = [5, 7, 13, 29, 65, 91]
0 1 2 3 4 5
所以第四次迭代完成指针移动到第五次…
这就是为什么你的循环没有覆盖65,因为它已经移动到前一个索引。
因此,你不应该将一个列表引用到另一个变量中,它仍然引用原始变量而不是副本。
ite = lis # Don’t do it will reference instead copy
所以使用list[::]复制列表。
现在你会付出,
[5, 7, 13, 29]
问题是你在迭代过程中从列表中删除了一个值,然后你的列表索引就会崩溃。
所以你可以试试列表理解。
它支持所有的可迭代对象,如list, tuple, dict, string等。
您可以使用列表推导式创建一个新列表,其中只包含您不想删除的元素:
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)
我需要做一些类似的事情,在我的情况下,问题是内存——我需要在一个列表中合并多个数据集对象,在对它们做了一些事情之后,作为一个新对象,并且需要摆脱我正在合并的每个条目,以避免重复所有它们并增加内存。在我的情况下,对象在一个字典而不是一个列表工作得很好:
```
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
```
如果当前列表项满足所需的条件,那么创建一个新列表可能是聪明的做法。
so:
for item in originalList:
if (item != badValue):
newList.append(item)
为了避免用新的列表名称重新编码整个项目:
originalList[:] = newList
注意,来自Python文档:
copy.copy (x) 返回x的浅拷贝。 copy.deepcopy (x) 返回x的深拷贝。