在python中,哪些容器在迭代过程中正确支持突变?
例如:
container = [1, 2, 3, 4]
for i in container:
print(i)
if i == 2:
container.append(8)
输出1 2 3 4 8
(列表可以在迭代过程中追加)。
但是,如果我将.append(8)
替换为.remove(1)
,则输出将变为1 2 4
(即,元素3
被跳过)。似乎列表迭代是在索引之上而不是元素之上,因此在迭代过程中只能安全地删除后续列表项(而非先前列表项)。
标准库中是否有任何容器确实允许在迭代过程中添加和删除元素,其行为是:
list.append
一样,],我想到的应用程序是事件回调的注册表。触发后,我希望这些回调能够eagerly注册或注销同一事件的其他回调。 (例如,如果我遍历了容器的临时副本,则需要等待事件第二次被触发才能使更改开始生效。)
list_iterator
类型使用内部索引,因此删除已访问的元素会导致问题,因为它会更改列表中所有更高值的索引。我建议您实际上并未从列表中删除任何值。而是将它们添加到另一个容器,也许是set
(如果它们是可哈希的)。这假定值是唯一的。但是,如果不是这样,您可能会遇到使用任何方法将其从列表中删除的问题。
container = [1, 2, 3, 4]
removed = set()
for i in container:
if i not in removed: # skip values that have been "removed"
print(i)
if i == 2:
removed.add(1) # since we've already visited 1, this has no real effect
removed.add(3) # this does work though, we won't print the 3
container.append(8) # additions of new elements work as normal
正如评论所建议的,该循环将打印出1
,2
,4
和8
。