2013-05-18 78 views
2

我想在迭代集合的同时删除其中的 个项目。有类似的问题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) 
+0

因为ZN中**对于i在ZN ** **是集(范围(N))** .. – matzone

+0

可能的[删除从一组得到控制而重复的项e迭代它](http://stackoverflow.com/questions/16551334/delete-items-from-a-set-while-iterating-over-it) –

回答

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循环中使用的原始设置。相反,您正在创建一个新的集合并指向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)代替,并保持价值你”的一组VE已经处理:

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 
+0

谢谢!复制粘贴您的建议代码给了我: '语法错误: Cosets.append(list(tmp))' – geo909

+0

@ geo909:什么版本的Python?我使用了集合理解,它只在Python 2.7和Python 3.x中可用。 –

+0

说实话,我正在使用鼠标(“笔记本”浏览器界面,通过我的浏览器访问我的大学圣人),你基本上是在Python中用额外的数学库进行编码(我猜,我对编码和这是相当新的)。我可以看到,sage版本是4.3(2009年12月),但在它的生命周期中,我找不到通过笔记本界面获取python版本的方法。另一个说明,我改变了一下代码,以便它适用于我,我会更新我的问题.. – geo909