我在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列表对象中的列表内容,而不是像其他答案一样只是重新设置一个引用(从以前的列表对象到新的列表对象)。
其他回答
最有效的方法是列表理解,很多人展示了他们的案例,当然,通过过滤器获得迭代器也是一个很好的方法。
过滤器接收一个函数和一个序列。Filter依次将传递的函数应用于每个元素,然后根据函数的返回值是True还是False来决定是否保留或丢弃该元素。
这里有一个例子(获取元组中的概率):
list(filter(lambda x:x%2==1, (1, 2, 4, 5, 6, 9, 10, 15)))
# result: [1, 5, 9, 15]
警告:你也可以不处理迭代器。迭代器有时比序列更好。
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等。
在某些情况下,您所做的不仅仅是一次过滤一个列表项,您希望在迭代时更改迭代。
这里有一个例子,事先复制列表是不正确的,反向迭代是不可能的,列表理解也是一个选项。
""" Sieve of Eratosthenes """
def generate_primes(n):
""" Generates all primes less than n. """
primes = list(range(2,n))
idx = 0
while idx < len(primes):
p = primes[idx]
for multiple in range(p+p, n, p):
try:
primes.remove(multiple)
except ValueError:
pass #EAFP
idx += 1
yield p
如果稍后将使用新列表,可以简单地将elem设置为None,然后在后面的循环中判断它,如下所示
for i in li:
i = None
for elem in li:
if elem is None:
continue
这样,你就不需要复制列表,而且更容易理解。
for i in range(len(somelist) - 1, -1, -1):
if some_condition(somelist, i):
del somelist[i]
你需要向后走,否则就有点像锯掉你坐着的树枝:-)
Python 2用户:用xrange替换range以避免创建硬编码的列表