I have a dict like so:
{ ('name', 'user1'): 'foo',
('user', 'user1'): 'bar',
('name', 'user2'): 'bat',
('user', 'user2'): 'baz' }
and I would like to convert to:
{ 'user1': {'name': 'foo', 'user': 'bar'},
'user2': {'name': 'bat', 'user': 'baz'} }
I can do this with a default dict easily, but I would like to use dict comprehension.
So far I have:
{user: {key:value for (key, user), value in my_dict.items()}}
But user is not inside the loop, so I name 'user' is not defined
error.
How can I achieve this with dict comprehension?
A dict comprehension can be used if both key and value have a direct one-on-one relationship with the items in the sequence.
However, your output values are based on multiple entries in the input sequence. Unless you can group the items into a sequence per second value in the tuple key, you have to use a defaultdict
setup.
Grouping is certainly possible with itertools.groupby()
but that would require sorting, making that less performant compared to a defaultdict
plus loop solution.
Using itertools.groupby
:
from itertools import groupby
user = lambda item: item[0][1]
{user: {key[0]: value for key, value in grouped}
for user, grouped in groupby(sorted(my_dict.items(), key=user), key=user)}
Output demo:
>>> {user: {key[0]: value for key, value in grouped}
... for user, grouped in groupby(sorted(my_dict.items(), key=user), key=user)}
{'user2': {'name': 'bat', 'user': 'baz'}, 'user1': {'name': 'foo', 'user': 'bar'}}
This is a O(n log n) solution, versus the O(n) complexity of a defaultdict
solution:
from collections import defaultdict
output = defaultdict(dict)
for (key, user), value in my_dict.iteritems():
output[user][key] = value
this is working fine:
from __future__ import print_function
from itertools import groupby
from operator import itemgetter
d=dict({('name', 'user1'): 'foo', ('user', 'user1'): 'bar',
('name', 'user2'): 'bat',
('user', 'user2'): 'baz' })
l = []
for key, val in d.items() :
l.append([key[1], key[0], val])
l.sort(key=itemgetter(0))
d_ = dict()
for key, group in groupby(l, lambda x: x[0]):
dic = dict()
for thing in group:
dic[thing[1]] = thing[2]
d_[key] = dic
note that groupby from itertools will work only if list was previously sorted.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.