TAGS :Viewed: 3 - Published at: a few seconds ago

[ Python for loop issues ]

I'm having issues replicating a for loop in python.

Here is my c style script with just the for loop aspects.

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

In python there it doesn't seem to be possible to subtract the index:

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

What is the best way to write the above c loop in Python?

Edit: Here is the loop working as I need in 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 

Answer 1


One idiomatic way to implement this is as follows:

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

where <condition> evaluates to true for elements that you want to keep.

For example, to get the even numbers between 0 and 9:

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

The main issue with your current code is that for i in item does not iterate over indices, but rather iterates over the elements themselves. While it is possible to use indices, it tends to lead fairly un-Pythonic code. Besides, there are complications associated with modifying a list while iterating over it.

Answer 2


Edit: Based on your posted algorithm, a little cleanup

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 ] )

I'm not sure what

I'm not sure the original PHP code would work either. Or it might, but only incidentally and certainly not efficiently. I assuming that you want to iterate through a list, removing items that match a certain value. You seem to have realized one of the essential issues with doing this is that you are modifying the very list you are trying to iterate over. This is very easy in Python:

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

Here you are making a copy of verts list to iterate over by [:] Each iteration uses c, which is a reference to an item in the verts -copy-. You then call remove() on the original list, with value c, which removes the -first- instance of the value c it encounters.

Obviously there is plenty of nuance here in different situations involving dictionaries, etc, but this should get you started.

Python tutorial is usually a good resource http://docs.python.org/2/reference/compound_stmts.html#for

Answer 3


You seem to think that i is an index in your code. It's not. i is a value from the list. To iterate over a range of indices use for i in range(len(item)):.

However a better way of deleting items from a list is to use a list comprehension, rather than manually iterating with an index and using del. List comprehensions will create a new list rather than modifying a new one, but hopefully they're still applicable for your use case.

Answer 4


Deleting items from a list while you iterate through it can be very tricky. The safest (least prone to error) way is to make a copy of the list, either containing only the elements you want or deleting the ones you don't want afterward.

Examples:

Using a for loop to create a new array of only even numbers in items. This is lengthier than writing a list comprehension, but probably more readable for someone new to python:

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

Output:

[0, 2, 4, 6, 8]

Using list comprehensions, this can be written as:

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

As an aside, the built-in function enumerate can be your friend when moving from C code. You can write a for loop like so:

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

Output:

0 foo
1 bar
2 spam
3 eggs