将字典列表转换为元组字典

3

如何将类似以下格式的字典列表转换:

[{'id':2, 'risk':'a'}, 
 {'id':1, 'risk':'a'}, 
 {'id':32,'risk':'aa'},
 {'id':2, 'risk':'aa'}, 
 {'id':7, 'risk':'a'}, 
 {'id':7, 'risk':'b'}]

将其转换为元组字典,排序后的结果如下所示:
{1:('a', ), 2:('a','aa'), 7:('a','b'), 32:('aa', )}

1
修正了你的单个元组,记住 ('a') 实际上不是元组,那只是使用括号来分组字符串 'a' - jamylak
4个回答

4

您可以使用defaultdict自动创建元组,然后只需遍历list_of_dicts:

list_of_dicts = [{'id':2, 'risk':'a'}, 
 {'id':1, 'risk':'a'}, 
 {'id':32,'risk':'aa'},
 {'id':2, 'risk':'aa'}, 
 {'id':7, 'risk':'a'}, 
 {'id':7, 'risk':'b'}]

from collections import defaultdict

dict_of_tuples = defaultdict(tuple)

for dct in list_of_dicts:
    dict_of_tuples[dct['id']] += (dct['risk'],)

这会导致:
>>> dict_of_tuples
defaultdict(<type 'tuple'>, {32: ('aa',), 1: ('a',), 2: ('a', 'aa'), 7: ('a', 'b')})

如果您想要一个排序后的字典:

>>> from collections import OrderedDict
>>> OrderedDict(sorted(dict_of_tuples.items()))
OrderedDict([(1, ('a',)), (2, ('a', 'aa')), (7, ('a', 'b')), (32, ('aa',))])

这对我来说是返回一个错误:Traceback(最近的调用最先): 文件“Dict_to_Tuples.py”的第13行,在<module>中 dict_of_tuples [dct ['id']] + = dct ['risk'] TypeError:只能将元组连接(而不是“str”)到元组 - user1793317
请注意,OrderedDict 只存在于 2.7 版本及以上,而该用户使用的是 2.6 版本。 - Burhan Khalid
@user1793317 你忘记把它转换成元组了 (dict['risk'],) - Burhan Khalid
你需要像答案中所发布的那样使用 dict_of_tuples[dct['id']] += (dct['risk'],)。请注意,() 包围着 dct['risk'] - RedBaron

3

dict.setdefault 方法可以轻松解决这种问题:

>>> lod = [{'id':2, 'risk':'a'}, 
           {'id':1, 'risk':'a'}, 
           {'id':32,'risk':'aa'},
           {'id':2, 'risk':'aa'}, 
           {'id':7, 'risk':'a'}, 
           {'id':7, 'risk':'b'}]
>>> dot = {}
>>> for d in lod:
        idnum, risk = d['id'], d['risk']
        dot.setdefault(idnum, []).append(risk)

>>> dot
{32: ['aa'], 1: ['a'], 2: ['a', 'aa'], 7: ['a', 'b']}

您也可以使用 collections.defaultdict 创建相同的效果,但这不会创建一个普通字典,而且需要理解工厂函数和零参数构造函数。


1
避免O(n^2)元组连接,这是一个好习惯。如果确实需要,最后总是可以将它们转换。 - jamylak

2

通常人们会在类似的情况下忘记使用dict.get方法。所以,使用基本的Python函数:

list_of_dicts = [{'id':2, 'risk':'a'}, 
    {'id':1, 'risk':'a'}, 
    {'id':32,'risk':'aa'},
    {'id':2, 'risk':'aa'}, 
    {'id':7, 'risk':'a'}, 
    {'id':7, 'risk':'b'}]

final_dict = {}

for item in list_of_dicts:
    final_dict[item['id']] = final_dict.get(item['id'], tuple()) + (item['risk'],)


>> {1: ('a',), 2: ('a', 'aa'), 7: ('a', 'b'), 32: ('aa',)}

0

用一种更冗长的方式来实现。不像agf的解决方案那样整洁,但它能够工作。

new_dict = {}
for x in my_dict_list: 
    m = new_dict.get(x['id'],())
    m += (x['risk'],)
    new_dict[x['id']] = m

输入

my_dict_list = [{'id':2, 'risk':'a'}, 
                {'id':1, 'risk':'a'}, 
                {'id':32,'risk':'aa'},
                {'id':2, 'risk':'aa'}, 
                {'id':7, 'risk':'a'}, 
                {'id':7, 'risk':'b'}]

输出

>>> new_dict
{32: ('aa',), 1: ('a',), 2: ('a', 'aa'), 7: ('a', 'b')}

1
你可以更改这个代码,创建元组,这样你就不需要第二个 for 循环了。在 if 语句中,new_dict[x['id']] = (x['risk'],),在 else 语句中,new_dict[x['id']] += (x['risk'],) - Burhan Khalid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接