将词典合并到列表字典中

Chr*_*ris 3 python merge dictionary numpy

我有三本词典:

dict1 = {'a': 1, 'b': 2, 'c': 3}
dict2 = {'b': 3, 'c': 4}
dict3 = {'c': 4, 'd': 4}
Run Code Online (Sandbox Code Playgroud)

我想将它们"合并"到列表中

merged_dict = {'a':[1, np.nan, np.nan],
               'b':[2, 3, np.nan],
               'c':[3, 4, 4],
               'd':[np.nan, np.nan, 4]}
Run Code Online (Sandbox Code Playgroud)

某些字典中有一些键而不是其他字典,这使得循环很麻烦.想知道最干净的方法是什么.

PM *_*ing 5

正如评论中所提到的,您需要首先迭代所有字典以收集所有密钥,否则无法知道每个字典中缺少哪些密钥.然后你可以merged_dict用字典理解来构建.

import numpy as np

dict1 = {'a': 1, 'b': 2, 'c': 3}
dict2 = {'b': 3, 'c': 4}
dict3 = {'c': 4, 'd': 4}

all_dicts = (dict1, dict2, dict3)

keys = {k for d in all_dicts for k in d}
merged_dict = {k: [d.get(k, np.nan) for d in all_dicts] for k in keys} 
print(merged_dict)   
Run Code Online (Sandbox Code Playgroud)

产量

{'a': [1, nan, nan], 'b': [2, 3, nan], 'c': [3, 4, 4], 'd': [nan, nan, 4]}
Run Code Online (Sandbox Code Playgroud)

可以将集合理解置于dict理解中,但我认为这会使代码难以阅读.

merged_dict = {k: [d.get(k, np.nan) for d in all_dicts] 
    for k in {k for d in all_dicts for k in d}}
Run Code Online (Sandbox Code Playgroud)

实际上,forset comp 中的双循环效率不高.对于小的dicts来说,它可能并不重要,但如果dicts很大,那么使用以下set.update方法以C速度执行其中一个循环会更有效:

keys = set()
for d in all_dicts:
    keys.update(d.keys())
Run Code Online (Sandbox Code Playgroud)

这可能更好:

keys = set().union(*all_dicts)
Run Code Online (Sandbox Code Playgroud)

谢谢,丹.D为那个建议!

这是另一种方式,使用itertools:

from itertools import chain
keys = set(chain.from_iterable(dicts))
Run Code Online (Sandbox Code Playgroud)

  • 甚至`keys = set().union(*all_dicts)`. (2认同)