这段代码是否有潜在危险?它会搞乱内外迭代吗?
for a in listA:
for b in listB:
if [... something...]:
... something else...
listA.remove(a)
listB.remove(b)
break
答案 0 :(得分:6)
这段代码是否有潜在危险?要看。在迭代序列时减小序列的大小会产生意外行为。
考虑这个例子
listA = [1,2,3,4]
>>> for a in listA:
listA.remove(a)
print a
因为,在移除项目时,除了它之外的所有项目都被推向左侧,您想要迭代的项目将自动移动到下一个元素
第一次迭代:
listA = [1,2,3,4]
^
|
_____________|
listA.remove(a)
listA = [2,3,4]
^
|
_____________|
print a
(outputs) 1
第二次迭代:
listA = [2,3,4]
^
|
_______________|
listA.remove(a)
listA = [2,4]
^
|
_______________|
print a
(outputs) 3
第三次迭代:
listA = [2,4]
^
|
_________________|
(Exits the Loop)
答案 1 :(得分:2)
更改迭代的序列通常是Python中的反模式。虽然你可以在特定情况下围绕它跳舞,但最好看看你是否可以构建一个只包含你需要的项目的新列表(或词典)。
答案 2 :(得分:1)
我同意jknupp - 删除列表中的项目可能比创建新项目更昂贵。然而,另一个技巧是倒退:
>>> l = range(5)
>>> for a in reversed(l):
... print a
... l.remove(a)
...
4
3
2
1
0