0

I have a snippet where I need to iterate over a list of items and remove the item whose job is done and continue looping on the remaining items.

as per python I can pass l to check condition for while loop as below :-

l = [node1, node2, node3]
while l:
    #do something
    for t in l:
        if t[wt] > 10:
            l.remove(t)

but as per this guide, it is not a good practice to modify a list while iterating over it.

So I changed my code to :-

l = [node1, node2, node3]
while len(l)>0:
    #do something
    for t in l:
        if t[wt] > 10:
            l.remove(t)

But then I see below pylint warning :-

[pylint] C1801:Do not use len(SEQUENCE) as condition value :- reference

Now what should be the approach here to handle this while loop with list which would not violate any of the above practices ?

Pabitra Pati
  • 457
  • 4
  • 12
  • 2
    `while l` and `while len(l) > 0'`mean exactly the same: the only list that evaluates to `False` in boolean context is the empty list. – Thierry Lathuille Feb 28 '19 at 14:51
  • @ThierryLathuille I would request you to kindly go through the whole query again. – Pabitra Pati Feb 28 '19 at 15:01
  • @Jean-François. please go through the problem statement before marking duplicate. – Pabitra Pati Feb 28 '19 at 15:01
  • ok, I really misread because of the inner loop. Reopened, and edited my answer – Jean-François Fabre Feb 28 '19 at 15:07
  • 1
    [How to remove items from a list while iterating?](https://stackoverflow.com/questions/1207406/how-to-remove-items-from-a-list-while-iterating) – benvc Feb 28 '19 at 15:12
  • yes, but here OP got fooled/didn't see the mixup between the while loop and the inner for loop. – Jean-François Fabre Feb 28 '19 at 15:14
  • 2
    @PabitraPati Your two versions of the code do exactly the same, the fact that Pylint gives a warning for the style of the second version doesn't change that. The problem remains the same: you remove items of the list while iterating over it. In short, you can replace the whole for loop by `l = [t for t in l if t[wt] <= 10]` – Thierry Lathuille Feb 28 '19 at 15:14

1 Answers1

4

By using len(l) in your condition, you didn't improve your code, it remains with the same error (removing items while iterating in the inner for loop), you just degraded the code, adding an irrelevant warning.

You are still removing elements while iterating in the inner loop.

for t in l:
    if t[wt] > 10:
        l.remove(t)

This could induce a subtle bug: if 2 consecutive elements need to be removed, the second one is skipped, and your code executes twice the processing you've eluded before the loop.

Instead, you should recompute l in the end using a list comprehension

l = [node1, node2, node3]
while l:
   # do something then rebuild `l` 
   l = [t for t in l if t[wt] <= 10]

more about this: How to remove items from a list while iterating?

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219