如何使用相同的键合并多个dicts?

Sal*_*lil 56 python merge dictionary

我有多个dicts /键值对,如下所示:

d1 = {key1: x1, key2: y1}  
d2 = {key1: x2, key2: y2}  
Run Code Online (Sandbox Code Playgroud)

我希望结果是一个新的dict(如果可能的话,以最有效的方式):

d = {key1: (x1, x2), key2: (y1, y2)}  
Run Code Online (Sandbox Code Playgroud)

实际上,我希望结果d是:

d = {key1: (x1.x1attrib, x2.x2attrib), key2: (y1.y1attrib, y2.y2attrib)}  
Run Code Online (Sandbox Code Playgroud)

如果有人告诉我如何获得第一个结果,我可以弄清楚其余部分.

Eli*_*sky 54

这是一个通用的解决方案,可以处理任意数量的字典,例如当键只在某些字典中时:

from collections import defaultdict

d1 = {1: 2, 3: 4}
d2 = {1: 6, 3: 7}

dd = defaultdict(list)

for d in (d1, d2): # you can list as many input dicts as you want here
    for key, value in d.iteritems():
        dd[key].append(value)

print(dd)
Run Code Online (Sandbox Code Playgroud)

显示:

defaultdict(<type 'list'>, {1: [2, 6], 3: [4, 7]})
Run Code Online (Sandbox Code Playgroud)

另外,要获得你的.attrib,只需append(value)改为append(value.attrib)

  • @AA:这真的很重要吗?在多个输入字典的更一般情况下构建元组将更加棘手,其中某些键并非随处可见,恕我直言 (6认同)

blu*_*ubb 24

假设所有密钥始终存在于所有dicts中:

ds = [d1, d2]
d = {}
for k in d1.iterkeys():
    d[k] = tuple(d[k] for d in ds)
Run Code Online (Sandbox Code Playgroud)

  • 我认为只是"对于d1中的k". (3认同)

Flu*_*lux 13

即使两个字典中的键不同,此函数也会合并两个字典:

def combine_dict(d1, d2):
    return {
        k: tuple(d[k] for d in (d1, d2) if k in d)
        for k in set(d1.keys()) | set(d2.keys())
    }
Run Code Online (Sandbox Code Playgroud)

例子:

d1 = {
    'a': 1,
    'b': 2,
}
d2 = {
    'b': 'boat',
    'c': 'car',
    'd': 'donkey',
}
combine_dict(d1, d2)
# Returns: {
#    'a': (1,),
#    'b': (2, 'boat'),
#    'c': ('car',),
#    'd': ('donkey'),
# }
Run Code Online (Sandbox Code Playgroud)


sat*_*esh 5

这是您可以使用的一种方法,即使两个字典没有相同的键也可以使用:

d1 = {'a':'test','b':'btest','d':'dreg'}
d2 = {'a':'cool','b':'main','c':'clear'}

d = {}

for key in set(d1.keys() + d2.keys()):
    try:
        d.setdefault(key,[]).append(d1[key])        
    except KeyError:
        pass

    try:
        d.setdefault(key,[]).append(d2[key])          
    except KeyError:
        pass

print d
Run Code Online (Sandbox Code Playgroud)

这将生成以下输入:

{'a': ['test', 'cool'], 'c': ['clear'], 'b': ['btest', 'main'], 'd': ['dreg']}
Run Code Online (Sandbox Code Playgroud)


Mah*_*chi 5

dict1 = {'m': 2, 'n': 4}
dict2 = {'n': 3, 'm': 1}
Run Code Online (Sandbox Code Playgroud)

确保键的顺序相同:

dict2_sorted = {i:dict2[i] for i in dict1.keys()}

keys = dict1.keys()
values = zip(dict1.values(), dict2_sorted.values())
dictionary = dict(zip(keys, values))
Run Code Online (Sandbox Code Playgroud)

给出:

{'m': (2, 1), 'n': (4, 3)}
Run Code Online (Sandbox Code Playgroud)

  • 我对此做了一个小研究。在Python(3.6+)的最新版本中,迭代顺序开始匹配插入顺序(参见例如[此处](https://docs.python.org/3/whatsnew/3.6.html#new-dict-implementation)),这使得你的代码通过了。但这被认为是不应该依赖的实现细节。我的第二个示例(参见[此处](https://gist.github.com/yugr/c65241789604ba73b0ee280a81d492fe))在使用旧Python 3.4的[onlinegdb](https://www.onlinegdb.com/online_python_debugger)中确实失败了。其他在线解释器使用较新的 Python,因此无法在那里重现问题。 (3认同)
  • `values()` 中元素的顺序未定义,因此您可能正在合并来自不相关键的值。 (2认同)