Is it legitimate to delete items from a dictionary in Python while iterating over it?
For example:
for k, v in mydict.iteritems():
if k == val:
del mydict[k]
The idea is to remove elements that don't meet a certain condition from the dictionary, instead of creating a new dictionary that's a subset of the one being iterated over.
Is this a good solution? Are there more elegant/efficient ways?
EDIT:
This answer will not work for Python3 and will give a
RuntimeError
.This happens because
mydict.keys()
returns an iterator not a list. As pointed out in comments simply convertmydict.keys()
to a list bylist(mydict.keys())
and it should work.A simple test in the console shows you cannot modify a dictionary while iterating over it:
As stated in delnan's answer, deleting entries causes problems when the iterator tries to move onto the next entry. Instead, use the
keys()
method to get a list of the keys and work with that:If you need to delete based on the items value, use the
items()
method instead:You can't modify a collection while iterating it. That way lies madness - most notably, if you were allowed to delete and deleted the current item, the iterator would have to move on (+1) and the next call to
next
would take you beyond that (+2), so you'd end up skipping one element (the one right behind the one you deleted). You have two options:.keys()
et al for this (in Python 3, pass the resulting iterator tolist
). Could be highly wasteful space-wise though.mydict
as usual, saving the keys to delete in a seperate collectionto_delete
. When you're done iteratingmydict
, delete all items into_delete
frommydict
. Saves some (depending on how many keys are deleted and how many stay) space over the first approach, but also requires a few more lines.Iterate over a copy instead, such as the one returned by
items()
: