Reputation: 5156
I tried this:
list = [[1], [2], [], [4], [5], [], [], [], [9]]
for e in list:
if e == []:
list.remove(e)
Then I got
>>> list
[[1], [2], [4], [5], [], [9]]
What happened?!
Upvotes: 3
Views: 89
Reputation: 5156
Language independent solution: iterating backwards
l = [[1], [2], [], [4], [5], [], [], [], [9]]
for e in reversed(l):
if e == []:
l.remove(e)
Upvotes: 0
Reputation: 239573
for e in list:
if e == []:
list.remove(e)
In this case, when e
is an empty list, that particular value is removed from the list. So, the next element in the list becomes the current element. In the next iteration, next element is taken from the list. Since the actual next element has been shifted backwards, the next to actual next element will be taken. So, there is a chance that elements are skipped, if there are more than one continuous matches.
In your case, lets say e
is at []
after the [2]
[[1], [2], [], [4], [5], [], [], [], [9]]
^
Since it is an empty list, it will be removed and the list becomes
[[1], [2], [4], [5], [], [], [], [9]]
^
In the next iteration, next element will be picked, so
[[1], [2], [4], [5], [], [], [], [9]]
^
In this case, we skipped [4]
silently. But, since it is expected in the output, it didn't make any difference. But consider the []
after [5]
,
[[1], [2], [4], [5], [], [], [], [9]]
^
That will be removed, so the list becomes like this
[[1], [2], [4], [5], [], [], [9]]
^
Now, in the next iteration, e
will refer the next element, which would be
[[1], [2], [4], [5], [], [], [9]]
^
So, the current empty list is removed and the [9]
becomes the current element. That is how, one of the empty lists is skipped.
Note: The bottom line is, never remove an item from a container, while you are iterating it.
Solution 1:
The most common technique is to use a copy of the list being iterated, for the iteration and the actual list will be modified in the loop. For example,
for e in list[:]: # `list[:]` is a shallow copy of `list`
if e == []:
list.remove(e)
Solution 2: (Preferred way to do this)
Use list comprehension, with a filtering condition to create a new list, like this
>>> [e for e in list if e]
[[1], [2], [4], [5], [9]]
Note the way empty lists are eliminated. Empty lists in Python are considered as Falsy values. So, if e
will evaluate to Truthy only when e
has atleast one element in it.
Upvotes: 2