Python list 可以在迭代期间发生变异,但不能在 deque 中发生变异。为啥?
Posted
技术标签:
【中文标题】Python list 可以在迭代期间发生变异,但不能在 deque 中发生变异。为啥?【英文标题】:Python list can be mutated during iteration but not deque. Why?Python list 可以在迭代期间发生变异,但不能在 deque 中发生变异。为什么? 【发布时间】:2021-12-20 16:09:40 【问题描述】:我需要识别数据结构中的元素满足条件,将它们保存在某个地方,最后从原始结构中删除。因此,我使用 for 循环而不是理解。
当尝试使用 deque 重新实现流程时,我收到以下错误:RuntimeError: deque mutated during iteration。
from collections import deque
def foo1(x):
pass
myDeque = deque([i for i in range(200)]) # i is in fact a complex, nested data structure
for index, e in enumerate(reversed(myDeque)):
if e % 2 == 0: # also more complex logic
foo1(e)
# myDeque.pop(index) # TypeError: pop() takes no arguments (1 given)
del myDeque[index] # RuntimeError: deque mutated during iteration
为什么我可以在迭代期间改变列表而不是双端队列?追加/插入两者都适用。
我目前正在使用从 deque 构建的临时列表。
from collections import deque
def foo1(x):
pass
myDeque = deque([i for i in range(200)])
temp = list(myDeque)
for index, e in enumerate(reversed(temp)):
if e % 2 == 0:
foo1(e)
temp.pop(index - 1)
myDeque = deque(temp)
【问题讨论】:
什么语言?蟒蛇? @Maurice - 抱歉,修改了 Q 发布您的代码,或者如果您已经解决了自己的问题,请将其删除。就目前而言,它对任何人都没有多大好处。 @rv.kvetch 添加了示例。 因为list
内置在语言中,并且在设计时没有这些保护措施;而deque
是在此之上实现的,以允许它检测问题的方式实现。请注意,仅仅因为您可以使用list
做到这一点,并不能使它成为编写代码的好方法。即使巧妙地使用reversed
,您也可以轻松创建错误。
【参考方案1】:
解决方法:创建一个临时列表
from collections import deque
def foo1(x):
pass
myDeque = deque([i for i in range(200)])
temp = list(myDeque)
for index, e in enumerate(reversed(temp)):
if e % 2 == 0:
foo1(e)
temp.pop(index - 1)
myDeque = deque(temp)
【讨论】:
以上是关于Python list 可以在迭代期间发生变异,但不能在 deque 中发生变异。为啥?的主要内容,如果未能解决你的问题,请参考以下文章
List addAll throw error :Unhandled Exception: 迭代期间并发修改:
在循环中更改 OrderedDict 中的键名会导致 RuntimeError: OrderedDict 在迭代期间发生突变
在列表迭代期间从 java.util.List 中删除元素时引发 ConcurrentModificationException? [复制]