dictionary with tuple keys

Ben Finney ben+python at benfinney.id.au
Tue Dec 15 02:25:38 EST 2009


Brandon Devine <your.master at gmail.com> writes:

> I am probably not thinking straight anymore about this problem. I have
> a dictionary with tuple keys in the format (a, b, A, B) and float
> values. I want to collect all the keys with identical (a, b...),
> disregarding whatever (... A, B) might be. Specifically, I want to sum
> the float values once I've collected these keys. I am staring at my
> screen, pondering ugly things, and I just know I must be missing a
> Pythonic solution. Any suggestions?

The Schwartzian transform, though primarily designed for unusual sorting
requirements, seems applicable here. It's a good tool to reach for in
many situations.

In other words: make a new dictionary, based on the key function you are
interested in.

In this case, I'll use ‘itertools.groupby’ to make a new sequence of
keys and values, and then extract the keys and values actually wanted.

    >>> import pprint
    >>> pprint.pprint(foo)
    {('a', 'b', 'A', 'B'): 1.1000000000000001,
     ('a', 'b', 'X', 'Y'): 2.2000000000000002,
     ('c', 'd', 'A', 'B'): 3.2999999999999998,
     ('e', 'f', 'P', 'Q'): 4.4000000000000004,
     ('e', 'f', 'R', 'S'): 5.5,
     ('e', 'f', 'T', 'U'): 6.5999999999999996}

    >>> import itertools
    >>> pprint.pprint(
    ...     dict(
    ...         (key, list(
    ...             x[1] for x in items))
    ...         for (key, items) in
    ...             itertools.groupby(
    ...                 sorted([
    ...                     (k[0:2], value)
    ...                     for (k, value) in foo.items()
    ...                     ]),
    ...                 lambda v: v[0]
    ...                 )
    ...         )
    ...     )
    {('a', 'b'): [1.1000000000000001, 2.2000000000000002],
     ('c', 'd'): [3.2999999999999998],
     ('e', 'f'): [4.4000000000000004, 5.5, 6.5999999999999996]}


Possibly someone could remove some of the processing in the middle
there, but I couldn't quickly see a way.

Certainly it might be clearer if written as one or more loops, instead
of iterators. But I find the above relatively clear, and using the
built-in iterator objects will likely make for a less buggy
implementation.

-- 
 \            “The whole area of [treating source code as intellectual |
  `\    property] is almost assuring a customer that you are not going |
_o__)               to do any innovation in the future.” —Gary Barnett |
Ben Finney



More information about the Python-list mailing list