我在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?我不知道怎么用这种方式把东西拿掉。
当前回答
你可以反过来尝试for- loops,这样对于some_list,你就可以这样做:
list_len = len(some_list)
for i in range(list_len):
reverse_i = list_len - 1 - i
cur = some_list[reverse_i]
# some logic with cur element
if some_condition:
some_list.pop(reverse_i)
这样索引是对齐的,并且不会受到列表更新的影响(无论是否弹出cur元素)。
其他回答
最有效的方法是列表理解,很多人展示了他们的案例,当然,通过过滤器获得迭代器也是一个很好的方法。
过滤器接收一个函数和一个序列。Filter依次将传递的函数应用于每个元素,然后根据函数的返回值是True还是False来决定是否保留或丢弃该元素。
这里有一个例子(获取元组中的概率):
list(filter(lambda x:x%2==1, (1, 2, 4, 5, 6, 9, 10, 15)))
# result: [1, 5, 9, 15]
警告:你也可以不处理迭代器。迭代器有时比序列更好。
建议列表推导的答案几乎是正确的,除了它们构建了一个全新的列表,然后给它一个与旧列表相同的名称,它们没有在适当的地方修改旧列表。这与Lennart建议的选择性删除不同——它更快,但如果您的列表是通过多个引用访问的,那么您只是重新设置了其中一个引用,而没有更改列表对象本身,这可能会导致微妙的、灾难性的错误。
幸运的是,它非常容易获得列表推导式的速度和所需的就地更改的语义——只是代码:
somelist[:] = [tup for tup in somelist if determine(tup)]
请注意与其他答案的细微区别:这个答案没有分配给一个裸名。它赋值给一个列表切片,恰好是整个列表,因此替换了同一Python列表对象中的列表内容,而不是像其他答案一样只是重新设置一个引用(从以前的列表对象到新的列表对象)。
如果当前列表项满足所需的条件,那么创建一个新列表可能是聪明的做法。
so:
for item in originalList:
if (item != badValue):
newList.append(item)
为了避免用新的列表名称重新编码整个项目:
originalList[:] = newList
注意,来自Python文档:
copy.copy (x) 返回x的浅拷贝。 copy.deepcopy (x) 返回x的深拷贝。
对于喜欢函数式编程的人:
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使您可以同时访问项和索引。反向是为了以后你要删除的索引不会改变。