我在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
答案 0 :(得分: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 :(得分: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,它是对verts -copy-中项目的引用。 然后使用值c调用原始列表上的remove(),这将删除遇到的值c的-first-实例。
显然,在涉及词典等的不同情况下,这里有很多细微差别,但这应该让你开始。
Python教程通常是一个很好的资源http://docs.python.org/2/reference/compound_stmts.html#for
答案 2 :(得分:1)
您似乎认为i
是代码中的索引。不是。 i
是列表中的值。要迭代一系列索引,请使用for i in range(len(item)):
。
但是,从列表中删除项目的更好方法是使用列表推导,而不是手动迭代索引并使用del
。列表推导将创建一个新列表而不是修改新列表,但希望它们仍然适用于您的用例。
答案 3 :(得分: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