【问题标题】:Convert a List of Dictionaries into a Dictionary of Tuples将字典列表转换为元组字典
【发布时间】:2013-04-01 18:58:55
【问题描述】:

如何转换如下所示的字典列表:

[{'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', )}

【问题讨论】:

  • 修复了你的单个元组,记住('a')实际上不是一个元组,那只是使用括号对字符串'a'进行分组。

标签: python list tuples python-2.6 dictionary


【解决方案1】:

您可以使用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',))])

【讨论】:

  • 这对我来说是一个错误:回溯(最近一次调用最后一次):文件“Dict_to_Tuples.py”,第 13 行,在 dict_of_tuples[dct['id']] += dct ['risk'] TypeError:只能将元组(不是“str”)连接到元组
  • 注意OrderedDict只在2.7,OP用的是2.6
  • @user1793317 你忘了把它变成一个元组(dict['risk'],)
  • 您需要dict_of_tuples[dct['id']] += (dct['risk'],),如答案中所述。注意() 周围的dct['risk']
【解决方案2】:

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) 元组连接。如果真的需要,它们总是可以在最后转换
【解决方案3】:

通常人们在类似情况下忘记使用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',)}

【讨论】:

    【解决方案4】:

    以更长的方式进行。不像 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')}
    

    【讨论】:

    • 你可以改变它来创建元组,这样你就不需要第二个for循环了。 new_dict[x['id']] = (x['risk'],)if,在elsenew_dict[x['id']] += (x['risk'],)
    猜你喜欢
    • 1970-01-01
    • 2010-09-20
    • 2017-06-07
    • 1970-01-01
    相关资源
    最近更新 更多