【问题标题】:Modifying a set while iterating over it在迭代时修改集合
【发布时间】:2013-05-13 14:53:24
【问题描述】:

我想在删除时迭代一个集合 它的项目。 deleting one item at the timelists 也有类似的问题,但确实如此 不适用于我的情况。

代码如下;我迭代一个 设置ZN 并在迭代结束时删除一个 一些项目(属于集合temp的项目)。但是 迭代仍在“原始” ZN 上进行。

如何修改此代码以更改设置的 ZN 而 我正在迭代它?

def CyclotomicCosets(q,n):
    N=q^n-1
    ZN=set(range(N))
    Cosets=[]
    for i in ZN:
        tmp=set([])
        for j in range(n):
            tmp.add( i*(q^j) %N)
        Cosets.append(list(tmp))
        ZN=ZN.difference(tmp) # <------------ Does not do what I want
    return(Cosets)

【问题讨论】:

标签: python set iteration sage


【解决方案1】:

使用while 循环和.pop() 值从集合中处理:

def CyclotomicCosets(q, n):
    N = q ^ n - 1
    ZN = set(range(N))
    Cosets = []
    while ZN:
        i = ZN.pop()
        tmp = {i * (q ^ j) % N for j in range(n)}
        Cosets.append(list(tmp))
        ZN -= tmp
    return Cosets

请注意,我用集合推导替换了您的内部 for 循环,以使其更快更紧凑。这些是在 Python 2.7 和 Python 3 中引入的,在早期版本的 python 中,您可以使用生成器表达式:

tmp = set(i * (q ^ j) % N for j in range(n))

您最初的错误是替换 ZN 而不是更新它:

ZN=ZN.difference(tmp)

这并没有改变您在for 循环中使用的原始集合。相反,您正在创建一个 new 集并将 ZN 引用指向该集。

但是,您不能在迭代 set 时对其进行修改,因此即使是就地差异也不会起作用;您将不得不使用 ZN -= tmpZN.difference_update(tmp) 但这会导致异常:

>>> ZN = set(range(3))
>>> for i in ZN:
...     ZN -= set([2])
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: Set changed size during iteration

更正后的代码给出:

>>> CyclotomicCosets(3, 5)
[[0], [0, 1, 2, 3], [0, 1, 4, 5], [0, 4, 5, 6]]

或者,改为遍历range(N),并保留一组您已经处理过的值:

def CyclotomicCosets(q, n):
    N = q ^ n - 1
    Cosets = []
    seen = set()
    for i in range(N):
        if i in seen: continue
        tmp = {i * (q ^ j) % N for j in range(n)}
        Cosets.append(list(tmp))
        seen |= tmp
    return Cosets

【讨论】:

  • 谢谢!复制粘贴您建议的代码给了我:Syntax Error: Cosets.append(list(tmp))
  • @geo909:什么版本的 Python?我使用了集合推导,它只在 Python 2.7 和 Python 3.x 中可用。
  • 老实说,我正在使用 sage(“笔记本”浏览器界面,通过我的浏览器访问我大学的 sage),您实际上是在用 Python 编写额外的数学库(我想,我很新的编码和这个)。我可以看到 sage 版本是 4.3(2009 年 12 月),但对于它的生命,我找不到通过笔记本界面获取 python 版本的方法。另一方面,我稍微更改了代码以便它适用于我,我会更新我的问题..
  • 顺便说一句,投票需要比我更多的声誉,抱歉 :)
  • Sage 4.3 已经很老了,我相信它使用的是 Python 2.6.4。我建议 @geo909 更新到最新的 Sage,它使用 2.7,并具有大量更新的功能……但如果她/他有一些自定义代码,那可能会有问题。
猜你喜欢
  • 2015-09-07
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多