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: 迭代期间并发修改:

在 R purr 中迭代读取/变异 csv 文件

当一个类符合一个包含变异函数的协议时会发生啥?

在循环中更改 OrderedDict 中的键名会导致 RuntimeError: OrderedDict 在迭代期间发生突变

python中的迭代

在列表迭代期间从 java.util.List 中删除元素时引发 ConcurrentModificationException? [复制]