1

我有一个这样的字典:

{ ('name', 'user1'): 'foo',
  ('user', 'user1'): 'bar',
  ('name', 'user2'): 'bat',
  ('user', 'user2'): 'baz' }

我想转换为:

{ 'user1': {'name': 'foo', 'user': 'bar'}, 
  'user2': {'name': 'bat', 'user': 'baz'} }

我可以很容易地使用默认的字典来做到这一点,但我想使用字典理解。

到目前为止,我有:

{user: {key:value for (key, user), value in my_dict.items()}}

但是用户不在循环内,所以我name 'user' is not defined出错了。

如何通过 dict 理解来实现这一点?

4

2 回答 2

3

如果键和值都与序列中的项目具有直接的一对一关系,则可以使用字典推导。

但是,您的输出值基于输入序列中的多个条目。除非您可以在元组键中将项目分组为每秒序列值,否则您必须使用defaultdict设置。

分组当然是可能的,itertools.groupby()但这需要排序,与defaultdict加循环解决方案相比,它的性能较低。

使用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)}

输出演示:

>>> {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'}}

这是一个 O(n log n) 的解决方案,而解决方案的复杂性是 O(n) defaultdict

from collections import defaultdict

output = defaultdict(dict)

for (key, user), value in my_dict.iteritems():
    output[user][key] = value
于 2013-05-07T18:12:45.300 回答
0

这工作正常:

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

请注意,仅当列表先前已排序时,来自 itertools 的 groupby 才会起作用。

于 2013-05-07T20:23:16.103 回答