0

I am trying to delete all values that are lower than 120 in res[1] and delete the value of the same index in res[0], for some reason the loop stops ..and doest continue to delete the end of the list.

thanks a lot for your support

here is the code:

def func ():
    res=([30.0,40.0,49.0,28.0,30.0,57.0], [0, 30.0,400.0,160.0, 30.0, 30.0])
    for i in res[1]:
        if i<120:
            ind=res[1].index(i)
            res[1].remove(i)
            del(res[0][ind])
        else:
            pass

    return res 

expected result is ([49.0, 28.0], [400.0, 160.0]) but i have this result ([49.0, 28.0, 30.0, 57.0], [400.0, 160.0, 30.0, 30.0])

Arkistarvh Kltzuonstev
  • 6,824
  • 7
  • 26
  • 56
Mhmd Qadi
  • 47
  • 1
  • 8

4 Answers4

2

Instead of checking i < 120, check i >= 120 and simply append the passing items in new list and return the tuple with these lists.

In [179]: def func(): 
     ...:     res=([30.0,40.0,49.0,28.0,30.0,57.0], [0, 30.0,400.0,160.0, 30.0, 30.0]) 
     ...:     r0, r1 = [], [] 
     ...:     for i in res[1]: 
     ...:         if i >= 120: 
     ...:             ind=res[1].index(i) 
     ...:             r1.append(i) 
     ...:             r0.append(res[0][ind])
     ...:     return (r0, r1) 
     ...:      

In [180]: func()
Out[180]: ([49.0, 28.0], [400.0, 160.0])
wjandrea
  • 28,235
  • 9
  • 60
  • 81
Mayank Porwal
  • 33,470
  • 8
  • 37
  • 58
1

Try this :

def func():
    res=([30.0,40.0,49.0,28.0,30.0,57.0], [0, 30.0,400.0,160.0, 30.0, 30.0])
    indices = [i for i,j in enumerate(res[1]) if j<120]
    res1 = [i for i in res[1] if i<120]
    res0 = [j for i,j in enumerate(res[0]) if i not in indices]
    result = (res0, res1)
    return result

Make a shallow copy of the second item of the tuple and loop over it. Modification needed in your code :

def func ():
    res=([30.0,40.0,49.0,28.0,30.0,57.0], [0, 30.0,400.0,160.0, 30.0, 30.0])
    res1 = res[1][:]
    for i in res1:
        if i<120:
            ind=res1.index(i)
            res1.remove(i)
            del(res[0][ind])
        else:
            pass
    res = (res[0], res1)
    return res 
Arkistarvh Kltzuonstev
  • 6,824
  • 7
  • 26
  • 56
1

You are modifying the list on which you are iterating which is not a goof practice. use

for i in res[1][:]:

It will result in creating new list for iteration

ajay gandhi
  • 545
  • 4
  • 13
1

This is practically a duplicate of How to remove items from a list while iterating?, but the code in that question only involves one list, not two.

Simply make a copy of res[1] and iterate over that:

res = ([30.0, 40.0, 49.0, 28.0, 30.0, 57.0], [0, 30.0, 400.0, 160.0, 30.0, 30.0])
for i in res[1].copy():  # <- Here
    if i < 120:
        ind = res[1].index(i)
        del res[1][ind]
        del res[0][ind]
print(res)  # -> ([49.0, 28.0], [400.0, 160.0])

BTW del is a statement, not a function, so it's clearer to not parenthesize its arguments.


Although IMHO, res[1].index(i) is a bit messy since you're already iterating, so I came up with this functional solution relying heavily on zip:

pairs = (t for t in zip(*res) if t[1] >= 120)
res = tuple(map(list, zip(*pairs)))  # Cast to tuple of lists

And a solution that borrows from Mayank's answer but uses zip:

r0, r1 = [], []
for x, y in zip(*res):
    if y >= 120:
        r0.append(x)
        r1.append(y)
res = r0, r1
wjandrea
  • 28,235
  • 9
  • 60
  • 81