我想在删除集合时进行迭代
项目。对于deletingone item at the time或lists也有类似的问题,但是它们确实存在
不适合我的情况。
代码如下;我遍历了
设置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)
最佳答案
使用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
循环中使用的原始设置。相反,您正在创建一个新集,并将ZN
引用指向该集。但是,在迭代
set
时不能对其进行修改,因此即使就地差异也不会起作用。您将必须使用ZN -= tmp
或ZN.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