Python3 词典理解

Python3 Dictionary Comprehension

我很难理解字典。

我有一个字典列表,其中每个字典都包含具有不同值的相同键:

  list_of_dictionaries = [{k1:v1, k2:v2}{k1:v3, k2:v4}{k1:v5, k2:v6}, ...]

我想要一个列表字典,其中每个键都有一个值,该值是在字典列表中该键下找到的那些值的列表:

  dictionary_of_lists = {k1:[v1,v3,v5], k2:[v2,v4,v6], ...}

目前我正在通过手动输入键并使用列表理解来获取值来创建这个单一的合并字典:

dictionary_of_lists = {
   k1:[i[k1] for i in list_of_dictionaries],
   k2:[i[k2] for i in list_of_dictionaries],
   ...
}

几个键还不错,但是超过二十个,重复代码就显得很乱了。我正在努力制定一个可以达到相同结果的字典理解。类似于“对于此列表中的每个字典,将与每个键对应的值添加到另一个字典中由相同键表示的列表中”?我已经尝试了 dict.update() 方法,该方法不允许我将值添加到列表中 - 它会删除并且 'updates' 已经存在的值。

请注意每一行的区别仅在于所使用的键。这意味着应该迭代键:

list_of_dictionaries  = [{1: 2, 2: 3}, {1: 4, 2: 5}, {1: 6, 2: 7}]

# Only safe if you know there will always be at least one dictionary
keys = list_of_dictionaries[0].keys()  

dictionary_of_lists = \
     {k: [i[k] for i in list_of_dictionaries]
      for k in keys}  # A second level of iteration to automate what you were doing manually before

print(dictionary_of_lists)
>>> {1: [2, 4, 6], 2: [3, 5, 7]}

一个简单的 for 循环就可以解决问题,而且效率很高。
遍历列表中所有字典的每个键。

>>> from collections import defaultdict
>>> res = defaultdict(list)
>>> for d in list_of_dictionaries:
...     for k, v in d.items():
...             res[k].append(v)
... 

使用Python collections 库:

from collections import defaultdict


list_of_dictionaries = [{'k1': 'v1', 'k2':'v2'},
                        {'k1':'v3', 'k2':'v4'},
                        {'k1':'v5', 'k2':'v6'}]

res = defaultdict(list)

for element in list_of_dictionaries:
    for key, value in  element.items():
        res[key].append(value)

print(dict(res))

out: {'k1': ['v1', 'v3', 'v5'], 'k2': ['v2', 'v4', 'v6']}

如果允许您使用 pandas,这是一个更简单的解决方案。

使用 pandas,您将得到以下结果:

import pandas as pd
list_of_dicts = [{'k1':'v1', 'k2':'v2'}, {'k1':'v3', 'k2':'v4'},
                 {'k1':'v5', 'k2':'v6'}, {'k1':'v7', 'k2':'v8'},
                 {'k1':'v9', 'k2':'v10'}]
df = pd.DataFrame(list_of_dicts)
k = {c:df[c].tolist() for c in df.columns}
print (k)

这个输出将是:

{'k1': ['v1', 'v3', 'v5', 'v7', 'v9'], 'k2': ['v2', 'v4', 'v6', 'v8', 'v10']}

通过这种方法,您可以继续添加任意数量的密钥,解决方案将是相同的。

import pandas as pd
list_of_dicts = [{'k1':'v1' , 'k2':'v2' , 'k3': 'v3'},
                 {'k1':'v4' , 'k2':'v5' , 'k3': 'v6'},
                 {'k1':'v7' , 'k2':'v8' , 'k3': 'v9'},
                 {'k1':'v10', 'k2':'v11', 'k3': 'v12'},
                 {'k1':'v13' ,'k2':'v14', 'k3': 'v15'}]
df = pd.DataFrame(list_of_dicts)
k = {c:df[c].tolist() for c in df.columns}
print (k)

这将导致:

{'k1': ['v1', 'v4', 'v7', 'v10', 'v13'], 'k2': ['v2', 'v5', 'v8', 'v11', 'v14'], 'k3': ['v3', 'v6', 'v9', 'v12', 'v15']}

唯一的限制是每组字典必须具有相同数量的元素(k1、k2、k3)。你不能有 (k1,k2) 和 (k1,k2,k3)。然后代码将中断,因为数据框正在寻找每列相同数量的元素。