简而言之:如果你确信所有新对象都无法通过somecond()
检查,那么你的代码运行良好,只是浪费了一些时间迭代新添加的对象。
在给出适当答案之前,您必须了解为什么在迭代时更改列表/字典被认为是一个坏主意。在使用for
语句时,Python
试图变得聪明,并返回动态计算的每个项。以list
为例,python
记住一个索引,并每次返回l[index]
给你。如果您更改了l
,则结果l[index]
可能会很混乱。
注意:这里有一个stackoverflow问题来证明这一点。
在迭代时添加元素的最坏情况是无限循环,请尝试(或不尝试,如果您能够读取错误)在Python REPL中执行以下操作:
import random
l = [0]
for item in l:
l.append(random.randint(1, 1000))
print item
它会不停地打印数字,直到内存被使用完或被系统/用户杀死。
为了理解原因,让我们讨论一些解决方案。以下是几种:
1. 复制原始列表
迭代原始列表,并修改复制的列表。
result = l[:]
for item in l:
if somecond(item):
result.append(Obj())
2. 控制循环结束的方式
不必将控制权交给 Python,您可以决定如何迭代列表:
length = len(l)
for index in range(length):
if somecond(l[index]):
l.append(Obj())
在迭代之前,计算列表长度,并仅循环length
次。
3. 将添加的对象存储在新列表中
不要修改原始列表,将新对象存储在新列表中,然后进行连接。
added = [Obj() for item in l if somecond(item)]
l.extend(added)