【问题标题】:Add to a deque being iterated in Python?添加到在 Python 中迭代的双端队列?
【发布时间】:2015-07-18 09:19:49
【问题描述】:

我在 Python 中有一个正在迭代的双端队列。有时双端队列在我交互时会发生变化,这会产生RuntimeError: deque mutated during iteration

如果这是一个 Python 列表而不是双端队列,我只会遍历列表的副本(通过像 my_list[:] 这样的切片,但由于切片操作不能在双端队列上使用,我想知道最pythonic 的处理方式是什么?

我的解决方案是导入复制模块,然后遍历一个副本,例如for item in copy(my_deque):,这很好,但由于我搜索了这个主题的高低,我想我会在这里发帖问?

【问题讨论】:

  • 为什么在迭代时要更改deque?你能显示一些代码吗?
  • 对于对双端队列进行的任何修改,您希望在迭代中发生什么?
  • 至于我为什么要改变它,这个双端队列是一个队列,用于在弹球机软件应用程序中保存一堆活动模式,并且在为模式提供服务时,它可以用于其他模式开始并添加到双端队列。我可以不调用迭代期间传入的任何内容,或者调用迭代期间删除的任何内容。真的我想像迭代开始时那样迭代双端队列,因此是副本。
  • 临时阻止更改是一种选择吗?然后你可以使用 threading.Lock 对象。

标签: python deque


【解决方案1】:

您可以通过创建列表来“冻结”它。没有必要将其复制到新的双端队列。列表当然就足够了,因为您只需要它来进行迭代。

for elem in list(my_deque):
    ...

list(x) 从任何可迭代的x 创建一个列表,包括双端队列,在大多数情况下,这是最 Pythonic 的方式。


请记住,此解决方案仅在双端队列在同一个线程(即循环内部)中被修改时才有效。否则,请注意 list(my_deque) 不是原子的,并且还在对双端队列进行迭代。这意味着如果另一个线程在运行时更改了双端队列,您最终会遇到相同的错误。如果您在多线程环境中,请使用锁。

【讨论】:

    【解决方案2】:

    虽然您可以从双端队列for elem in list(deque) 创建一个列表,但如果它是一个经常使用的函数,这并不总是最佳的:它会产生性能成本,尤其是。如果双端队列中有大量元素,并且您不断将其更改为 array 结构。

    无需创建列表的可能替代方法是使用带有一些布尔变量的while 循环来控制条件。这提供了 O(1) 的时间复杂度。

    【讨论】:

    • while 循环对于添加元素时的破坏性迭代很有用,但对提问者的用例帮助不大。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-14
    • 2015-06-26
    • 2010-10-29
    • 2019-10-07
    • 2017-05-20
    • 2021-12-13
    • 2010-12-12
    相关资源
    最近更新 更多