Iterating over dict and removing some elements

Bryan bryanjugglercryptographer at yahoo.com
Fri May 14 12:33:10 EDT 2010


Adi Eyal  wrote:
> > Bryan:
> > Terry Reedy wrote:
> > [...]
> >> for k in [k for k in d if d[k] == 'two']:
> >>          d.pop(k)
>
> > We have a winner.
>
> also
>
> foo = lambda k, d : d[k] == "two"
> d = dict([(k, d[k]) for k in d.keys() if not foo(k, d)])
>
> incidentally, this is marginally slower than pops and dels but has the
> benefit of not modifying the original dict if that's what you need.

Well, I guess, sure. The original problem in this tread was about
modifying the dict over which we are iterating. If you create a new
dict instead, that problem just goes away.

In Python 3.X, and in Python 2.X starting with 2.4, you can drop the
square brackets and avoid creating an extra temporary list:

d = dict((k, d[k]) for k in d.keys() if not foo(k, d))

You can also drop .keys() in Python 3.X or current Python 2.X:

d = dict((k, d[k]) for k in d if not foo(k, d))

Passing the dict to foo() seems inelegant. You could use:

foo = lambda val: val == "two"
d = dict((k, d[k]) for k in d if not foo(d[k]))

I'm sticking with my call of Terry Reedy's last solution as winner. It
solves the originally-stated problem, works correctly and efficiently
in both Python 3.X and current Python 2.X, and there is not a bracket
in it that does not need to be there.

--
--Bryan



More information about the Python-list mailing list