When running this python code:
shapes = [{"label": "bad_stuff"}, {"label": "cat"}, {"label": "cat"},{"label": "cat"}, {"label": "bad_stuff"}, {"label": "bad_stuff"}]
for elem in shapes:
if elem['label'] == "bad_stuff":
shapes.remove(elem)
... I get this result:
[{'label': 'cat'}, {'label': 'cat'}, {'label': 'cat'}, {'label': 'bad_stuff'}]
Why does not the code remove the last element in the list and how can I solve it?
CodePudding user response:
Because you are modifying list during for loop. Let's see what's happening in your code:
On 1st interation it removes shapes[0] item.
2, 3, 4 iterations do not satisfy condition, so passed.
On 5th iteration the elem is {"label": "bad_stuff"}
, and your shapes looks like this:
[{"label": "cat"}, {"label": "cat"},{"label": "cat"}, **{"label": "bad_stuff"}**, {"label": "bad_stuff"}]
So when you remove(elem)
on this step, it removes last item in the list.
And since you removed last item - iteation stops.
There is solution to your problem:
shapes = [{"label": "bad_stuff"}, {"label": "cat"}, {"label": "cat"},{"label": "cat"}, {"label": "bad_stuff"}, {"label": "bad_stuff"}]
cat_shapes = []
for elem in shapes:
if elem['label'] != "bad_stuff":
cat_shapes.append(elem)
Another solution mentioned in comments by DanielB :
cat_shapes = [elem for elem in shapes if elem['label'] != "bad_stuff"]
CodePudding user response:
You can do this with filter
,
list(filter(lambda x:x['label'] != 'bad_stuff', shapes))
# [{'label': 'cat'}, {'label': 'cat'}, {'label': 'cat'}]