expression form of one-to-many dict?

Tim Peters tim.peters at gmail.com
Fri Dec 17 22:32:43 CET 2004


[Steven Bethard]
> So I end up writing code like this a fair bit:
>
> map = {}
> for key, value in sequence:
>     map.setdefault(key, []).append(value)
>
> This code basically constructs a one-to-many mapping -- each
> value that a key occurs with is stored in the list for that key.
>
> This code's fine, and seems pretty simple, but thanks to generator
> expressions, I'm getting kinda spoiled. ;)  I like being able to do
> something like the following for one-to-one mappings:
>
>     dict(sequence)
>
> or a more likely scenario for me:
>
>     dict((get_key(item), get_value(item) for item in sequence)
>
> The point here is that there's a simple sequence or GE that I can
> throw to the dict constructor that spits out a dict with my one-to-
> one mapping.

It's a simple sequence because it's a simple task.  It's even simpler
than perhaps it "should be", since it arbitrarily decides that, if
more than one instance of some key is seen, it will only remember the
value associated with the last instance of that key.

> Is there a similar expression form that would spit out my one-to-
> manymapping?

There's a straightforward one-liner in 2.4 (but not notably concise),
if your keys are totally ordered:

from itertools import groupby
d = dict((k, map(get_value, g))
            for k, g in groupby(sorted(sequence, key=get_key),
                                       key=get_key))

The real purpose of that is to increase your appreciation for your
original spelling <0.2 wink>.



More information about the Python-list mailing list