【问题标题】:How does java's iterator.remove() translate to python?java的iterator.remove()如何翻译成python?
【发布时间】:2013-01-13 22:52:12
【问题描述】:

我有一个需要迭代的 python 集,对于每个元素,检查它是否满足约束,如果满足,则将其删除并将其添加到另一个可能已经非空的集合中。我可以将它添加到缓冲区,然后在循环完成后,遍历缓冲区并从集合中删除其内容,但必须有更好的方法来做到这一点。

这是我想要做的:

for elem in S:
  if (P(elem)):
    S.remove(elem)
    T.add(elem)

这不起作用。

以下是可行但不干净的修复:

B = set()
for elem in S:
  if (P(elem)):
    B.add(elem)
    T.add(elem)
for elem in B:
  S.remove(elem)

编辑: 最好的解决方案似乎是:

for elem in S.copy():
  if (P(elem)):
    S.remove(elem)
    T.add(elem)

【问题讨论】:

  • 从上下文来看,我猜你正在处理一个 list,而不仅仅是任何可迭代的(通常不是直接可寻址或可变的)。
  • 此功能称为“分区”;然而,我知道没有这样的标准 Python 构造,尽管它很容易创建。请参阅stackoverflow.com/questions/4578590/…(其中一些允许惰性迭代器;其他强制评估)

标签: java python concurrency iterator


【解决方案1】:

对于列表,在迭代之前创建一个副本:

for elem in S[:]:

[:] 切片符号创建完整列表的副本。在迭代列表时,您不能以其他方式从列表中删除元素。

【讨论】:

    【解决方案2】:

    一种选择是使用列表推导创建T,然后从S 中删除T 中的所有元素。

    T = set([elem for elem in S if P(elem)])
    S = S - T
    

    【讨论】:

    • 这仅适用于 T 开头为空的情况。让我的问题对我来说不平凡的事情是 T 可能是非空的。
    • @user1123936:一种选择是使用临时集X,然后在答案中的代码之后将X 添加到T
    【解决方案3】:

    如果遍历列表两次并为每个项目调用两次P() 不是问题,这将是最易读的解决方案::

    T = [x for x in S if P(elem)]
    S = [x for x in S if not P(elem)]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-05
      • 2021-03-06
      • 2018-02-08
      • 2021-12-03
      • 1970-01-01
      • 1970-01-01
      • 2015-11-14
      • 1970-01-01
      相关资源
      最近更新 更多