Reputation: 3375
I have the following data:
a = {1: {'data': 243}, 2: {'data': 253}, 4: {'data':243}}
And I want to turn it around, so that the key is the values, and the data values is the keys. So first try:
b = dict(map(lambda id: (a[id]['data'], id, a))
But when I do this, the 1 gets overwritten by the 4, so result will be:
{243: 4, 253: 2}
So what I would like to get is a structure like this:
{243: [1, 4], 253: [2]}
How do I do this?
Upvotes: 0
Views: 76
Reputation: 338228
This can be done with a dict comprehension and itertools.groupby()
, but since dicts are not ordered, we must work with a sorted list, because groupby
expects pre-sorted input.
from itertools import groupby
a = {1: {'data': 243}, 2: {'data': 253}, 4: {'data': 243}}
# key extractor function suitable for both sorted() and groupby()
keyfunc = lambda i: i[1]['data']
{g[0]: [i[0] for i in g[1]] for g in groupby(sorted(a.items(), key=keyfunc), key=keyfunc)}
here g
is a grouping tuple (key, items)
, where
g[0]
is whatever keyfunc
extracts (in this case the 'data'
value), and g[1]
is an iterable over dict items, i.e. (key, value)
tuples, hence the additional list comprehension to extract the keys only.result:
{243: [1, 4], 253: [2]}
Upvotes: 1
Reputation: 2182
I felt the below code is more readable and simpler way of approaching your problem.
from collections import defaultdict
a = {1: {'data': 243}, 2: {'data': 253}, 4: {'data':243}}
result = defaultdict(list)
for k, v in a.items():
result[v['data']].append(k)
print(result)
Output:
defaultdict(<class 'list'>, {243: [1, 4], 253: [2]})
Upvotes: 3