【问题标题】:Transform list of dictionaries into dictionary of lists将字典列表转换为列表字典
【发布时间】:2021-10-13 21:16:31
【问题描述】:

我有一个具有相同键的字典列表。此外,每个字典只有两个“键:值”对。我想将字典列表转换为具有两个键的单个字典,每个键代表一个列表值。这样相同键的值位于一个列表中。

我想出了以下方法,顺便说一句,效果很好。但我希望知道是否有更好的实用方法。

词典列表:

my_list = [{'old_price': None, 'price': '5,75'}, {'old_price': None, 'price': '5,90'}, {'old_price': None, 'price': '5,95'}, {'old_price': None, 'price': '10,15'}, {'old_price': None, 'price': '19,90'}, {'old_price': None, 'price': '34,90'}, {'old_price': None, 'price': '46,50'}, {'old_price': None, 'price': '24,90'}]

字典列表到列表字典:

single_dict = {"old_price": [item['old_price'] for item in my_list], "price":[item['price'] for item in my_list]}

结果字典:

{'old_price': [None, None, None, None, None, None, None, None], 'price': ['5,75', '5,90', '5,95', '10,15', '19,90', '34,90', '46,50', '24,90']}

【问题讨论】:

  • 这篇文章对你有帮助吗:*.com/questions/38987/…
  • 您不喜欢您的解决方案的哪些方面?对我来说它看起来很好
  • @CyrillePontvieux 那里的任何答案是否显示了如何列出字典中的所有值?看起来他们只是覆盖了公共键。
  • @barmar 回答 OP 问题:如何将多个字典合并为一个;不是如何仅提取值,但解决方案几乎相同,只需在迭代/解构时使用集合或列表而不是字典
  • 我检查了帖子,但它似乎对我不起作用。 @CyrillePontvieux

标签: python list dictionary data-structures


【解决方案1】:

使用defaultdict,您可以使算法O(N),在列表上循环一次。

>>> my_list = [{'old_price': None, 'price': '5,75'}, {'old_price': None, 'price': '5,90'}, {'old_price': None, 'price': '5,95'}, {'old_price': None, 'price': '10,15'}, {'old_price': None, 'price': '19,90'}, {'old_price': None, 'price': '34,90'}, {'old_price': None, 'price': '46,50'}, {'old_price': None, 'price': '24,90'}]

>>> from collections import defaultdict
>>> d = defaultdict(list)  # will create a list for every missing entry
>>> for adict in my_list:
...    for key, value in adict.items():
...       d[key].append(value)
...    
>>> d
defaultdict(<class 'list'>, {'old_price': [None, None, None, None, None, None, None, None], 'price': ['5,75', '5,90', '5,95', '10,15', '19,90', '34,90', '46,50', '24,90']})

如果你事先知道你需要的键,你可以用固定分配交换循环(但是时间成本非常小):

>>> for adict in my_list:
...    d["old_price"].append(adict["old_price"])
...    d["price"].append(adict["price"])
...

【讨论】:

  • "使用defaultdict,可以使算法O(N)"。我喜欢defaultdict,但这不是魔术,也不会真正“制造”任何 O(N)。事实上,OP 在他们的问题中建议的解决方案已经是 O(N)。
  • 这并不神奇,但如果缺少一个键,您将拥有一个默认的“空白”元素。 OP 提出的算法是 O(N*M),其中 M 是从小字典中提取的键的数量 - 在这种情况下 M=2。
  • 你声称你的代码不是 O(N*M)?
  • 第一个提供的版本确实是O(N*M);但是对于第二个来说,情况并非如此。
【解决方案2】:

迭代到您的dict,然后创建一个带有检查器的新字典,无论是否已创建。

my_list = [{'old_price': None, 'price': '5,75'}, {'old_price': None, 'price': '5,90'}, {'old_price': None, 'price': '5,95'}, {'old_price': None, 'price': '10,15'}, {'old_price': None, 'price': '19,90'}, {'old_price': None, 'price': '34,90'}, {'old_price': None, 'price': '46,50'}, {'old_price': None, 'price': '24,90'}]
result = {}
for each_dict in my_list:
    for k in each_dict:
        if (k in result): 
            result[k].append(each_dict[k])
        else:
            result[k] = [each_dict[k]]

print(result)

输出:

{'old_price': [None, None, None, None, None, None, None, None], 'price': ['5,75', '5,90', '5,95', '10,15', '19,90', '34,90', '46,50', '24,90']}

【讨论】:

    【解决方案3】:

    处理数据,我习惯用pandas...

    import pandas as pd
    
    my_list = [{'old_price': None, 'price': '5,75'}, {'old_price': None, 'price': '5,90'},
               {'old_price': None, 'price': '5,95'}, {'old_price': None, 'price': '10,15'},
               {'old_price': None, 'price': '19,90'}, {'old_price': None, 'price': '34,90'},
               {'old_price': None, 'price': '46,50'}, {'old_price': None, 'price': '24,90'}]
    
    df = pd.DataFrame(my_list)
    
    columns = df.columns.tolist()
    data = {}
    // merge same key
    for key in columns:
        data[key] = df[key].tolist()
    
    print(data)
    
    

    【讨论】:

    • 我正在寻找仅使用纯 python 的练习,而不是使用 pandas。
    • @UğurEren - 您应该将此约束添加到问题中,而不是评论它被埋葬的地方。 T
    【解决方案4】:

    试试这个:

    values = list(map(list, zip(*[item.values() for item in my_list])))
    single_dict = { 'old_price':values[0], 'price':values[1] }
    

    【讨论】: