2013-03-16 186 views
2

我遇到了在python中复制for循环的问题。Python for循环问题

这是我的c风格的脚本,只有for循环方面。

for ($c=0 ; $c<size($verts); $c++) 
{ 
//// do some code here 
$verts = remove($verts[c],$verts); /// remove this item from the $verts list 
$c-=1; /// lower the index becuase an item was removed 
    for ($n=0 ; $n<size($verts); $n++) 
     { 
     if($condition) 
     $verts = remove($verts[$n],$verts); /// remove this item from the $verts list 
     $n-=1; /// lower the index becuase an item was removed 
     }   
}   

在蟒蛇有它似乎并不才有可能减去指数:

item = range(10); 
for i in item : 
del item[i] 
i-=1 # this doesn't do anything for the next interation 

什么是用Python语言编写上面的C循环的最佳方式?

编辑: 这里是循环的工作,因为我需要在Python

count = range(len(vtx)) 
for num in count: 
if len(vtx) != 0:  
    p.append ([]); p[len(p)-1].append(vtx[0]) 
    v.append ([]); v[len(p)-1].append(vec[0])  
    a = vec[0] 
    del vtx[0]  
    del vec[0] 
    count2 = range(len(vtx)) 
    n2 = 0; 
    for num2 in count2: 
     b = vec[n2] 
     distance = math.sqrt((a[0] - b[0])**2 + (a[1]- b[1])**2 + (a[2]- b[2])**2); 
     if distance <= threshold : 
      p[len(p)-1].append (vtx[n2]) 
      v[len(p)-1].append (vec[n2]) 
      vtx.remove(vtx[n2]) 
      vec.remove(vec[n2]) 
     else: 
      n2+=1 

回答

3

编辑:根据您发布的算法,一点点清理

p, v = [[vtx.pop(0)]],[[vec.pop(0)]] 
while len(vtx):  
    x = vtx.pop(0) 
    b = vec.pop(0) 
    a = v[ -1 ][ 0 ]  
    if threshold >= math.sqrt((a[0] - b[0])**2 + (a[1]- b[1])**2 + (a[2]- b[2])**2): 
     v[ -1 ].append(b) 
     p[ -1 ].append(x) 
    else: 
     v.append([ b ]) 
     p.append([ x ]) 

我不知道我不知道原来的PHP代码将工作,要么什么

。或者它可能,但只是偶然,当然不是有效的。我假设你想遍历一个列表,删除与某个值相匹配的项目。你似乎已经意识到这样做的一个基本问题是你正在修改你正在尝试迭代的列表。这是很容易在Python:

for c in verts[:]: 
    if remove_condition(c): 
     verts.remove(c) 

在这里,你正在绿党的副本中列出了遍历[:] 每次迭代使用C,这是在绿党-copy-到项目的引用。 然后,您使用值c调用原始列表上的remove(),该值将删除它遇到的值c的-first-实例。

很明显,在涉及字典等不同情况下,这里有很多细微差别,但这应该让你开始。

Python的教程通常是一个很好的资源http://docs.python.org/2/reference/compound_stmts.html#for

+0

感谢所有的答案。我最终做了一些不太pythonic的事情,因为我仍然对索引有很多麻烦,并且意识到我可以简化我的c代码。 (请参阅带有工作代码的更新问题)但是所有的答案都很有帮助,现在我明白了python的工作原理。 – fghajhe 2013-03-16 19:40:46

+0

@fghajhe我发布了一个基于你的编辑的版本,这个版本更容易遵循。不确定它是否相关,但你的算法是依赖于顺序的。如果你重新排列你的vtx/vec对,你会得到不同的结果。 – 2013-03-17 00:03:49

3

一种惯用的方式来实现,这是如下:

items = [el for el in items if <condition>] 

其中<condition>计算结果为true的元素,你想保持

例如,为了获得偶数0到9之间:

items = list(range(10)) 
items = [el for el in items if el % 2 == 0] 

与您现有的代码的主要问题是,for i in item不随指数迭代,但在内容本身,而迭代。尽管可以使用索引,但它往往会导致相当的非Pythonic代码。此外,在迭代它的同时修改列表还有一些复杂性。

1

您似乎认为i是您的代码中的索引。不是。 i是来自列表的值。要遍历一系列索引,请使用for i in range(len(item)):

但是,从列表中删除项目的更好方法是使用列表理解,而不是手动迭代索引并使用del。列表解析将创建一个新列表,而不是修改一个新列表,但希望它们仍适用于您的用例。

1

从列表中删除项目,而你遍历它可以是非常棘手的。最安全(最不容易出错)的方式是制作一个列表的副本,只包含你想要的元素或删除之后你不想要的元素。

例子:

使用for循环中items创建只有偶数的一个新的数组。这比写一个列表理解冗长,但可能有人新的Python更加易读:

items = range(10) 
new_items = [] 
for item in items: 
    if item % 2 == 0: 
     new_items.append(item) 
items = new_items 
print items 

输出:

[0, 2, 4, 6, 8] 

使用列表内涵,这可以写成:

items = range(10) 
items = [item for item in items if item % 2 == 0] 

另外,从C代码移动时,内置函数enumerate可以成为您的朋友。你可以像这样写一个for循环:

items = ['foo', 'bar', 'spam', 'eggs'] 
for i, item in enumerate(items): 
    print i, item 

输出:

0 foo 
1 bar 
2 spam 
3 eggs