Chris Pratt
Chris Pratt

Reputation: 239260

Creating a dict from list of key, value tuples while maintaining duplicate keys

So I've got a comprehension to the effect of:

dict((x.key, x.value) for x in y)

The problem, of course, is that if there's multiple x.keys with the same value, they get collapsed with the last x.value with that particular x.key as the only surviving member. I want to actually make the values of the resulting dict a list:

{
    'key1': ['value1'],
    'key2': ['value2', 'value3', 'value4'],
    'key3': ['value5'],
    # etc.
}

Is this logic possible with a comprehension?

Upvotes: 16

Views: 20520

Answers (3)

Eric O. Lebigot
Eric O. Lebigot

Reputation: 94475

You can add the elements one by one to a dictionary that contains empty lists by default:

import collections

result_dict = collections.defaultdict(list)
for x in y:
    result_dict[x.key].append(x.value)

You can also do something very similar without having to use the collections module:

result_dict = {}
for x in y:
    result_dict.setdefault(x.key, []).append(x.value)

but this is arguably slightly less legible.

An equivalent, more legible (no need to "parse" the less common setdefault) but more pedestrian, base Python approach is:

result_dict = {}
for x in y:
    if x.key not in result_dict:
        result_dict[x.key] = []
    result_dict[x.key].append(x.value)

The first solution is clearly the preferred one, as it is at the same time concise, legible, and fast.

Upvotes: 28

Rob Marrowstone
Rob Marrowstone

Reputation: 1264

I'm not saying it's the right thing to do, but, just out of sheer intellectual curiosity..

You can use itertools.groupby and lambda to do it in one dict comprehension, if that's what you really want to do: (where l is the list of tuples you want to make a dict out of:

dict((k, [v[1] for v in vs]) for (k, vs) in itertools.groupby(l, lambda x: x[0]))

Upvotes: 2

Stefan Kanev
Stefan Kanev

Reputation: 3040

Nope. You cannot do this in a comprehension.

But you can use itertools.groupby.

Upvotes: 2

Related Questions