pyhton list – remove dictionares with certain key
Question:
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?
Answers:
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"]
You can do this with filter
,
list(filter(lambda x:x['label'] != 'bad_stuff', shapes))
# [{'label': 'cat'}, {'label': 'cat'}, {'label': 'cat'}]
If you want to remove matching elements from list please check below code
def remove_bad_stuff(shapes, remove_value):
for elem in shapes:
if elem['label'] == remove_value:
shapes.remove(elem)
remove_bad_stuff(shapes, remove_value)
shapes = [{"label": "bad_stuff"}, {"label": "cat"}, {"label": "cat"},{"label": "cat"}, {"label": "bad_stuff"}, {"label": "bad_stuff"}]
remove_bad_stuff(shapes,"bad_stuff")
print(shapes)
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?
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"]
You can do this with filter
,
list(filter(lambda x:x['label'] != 'bad_stuff', shapes))
# [{'label': 'cat'}, {'label': 'cat'}, {'label': 'cat'}]
If you want to remove matching elements from list please check below code
def remove_bad_stuff(shapes, remove_value):
for elem in shapes:
if elem['label'] == remove_value:
shapes.remove(elem)
remove_bad_stuff(shapes, remove_value)
shapes = [{"label": "bad_stuff"}, {"label": "cat"}, {"label": "cat"},{"label": "cat"}, {"label": "bad_stuff"}, {"label": "bad_stuff"}]
remove_bad_stuff(shapes,"bad_stuff")
print(shapes)