使用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
orZN.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