2

我在 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
         }        
}         

在 python 中,似乎不可能减去索引:

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 
4

4 回答 4

3

一种惯用的实现方式如下:

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

<condition>对于要保留的元素, where的计算结果为 true 。

例如,要获得 0 到 9 之间的偶数:

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

当前代码的主要问题是它for i in item不会迭代索引,而是迭代元素本身。虽然可以使用索引,但它往往会导致相当非 Pythonic 的代码。此外,在迭代列表时修改列表会带来一些复杂性。

于 2013-03-16T15:24:45.990 回答
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)

在这里,您正在制作 verts 列表的副本以通过 [:] 进行迭代每次迭代都使用 c,它是对 verts -copy- 中项目的引用。然后在原始列表上调用 remove(),值为 c,它会删除它遇到的值 c 的第一个实例。

显然,在涉及字典等的不同情况下,这里有很多细微差别,但这应该可以帮助您入门。

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

于 2013-03-16T15:37:35.693 回答
1

您似乎认为这i是您代码中的索引。它不是。i是列表中的一个值。要迭代一系列索引,请使用for i in range(len(item)):.

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

于 2013-03-16T15:25:53.963 回答
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]

enumerate顺便说一句,从 C 代码迁移时,内置函数可以成为您的朋友。您可以像这样编写一个 for 循环:

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

输出:

0 foo
1 bar
2 spam
3 eggs
于 2013-03-16T15:51:15.513 回答