在python中合并两个dicts,不允许重复

Mic*_*man 4 python merge dictionary

此问题与类似的字典合并问题的不同之处在于,冲突的重复项应该失败,或者返回False.其他解决方案使用优先规则来决定如何管理一个键可能映射到两个不同的变量.

如何在python中有效地合并两个dicts.例如,考虑:

d1 = {'x': 'a', 'y': 'b', 'z': 'c'}
d2 = {'z': 'c', 'w': 'r'}
d3 = {'z': 'd', 'w': 'r'}
Run Code Online (Sandbox Code Playgroud)

因此,合并字典1和2的结果将是

{'x': 'a', 'y': 'b', 'z': 'c', 'w': 'r'}
Run Code Online (Sandbox Code Playgroud)

但是1和3或2和3的合并应该失败,因为z存在冲突.

我的解决方案是:

def merge_dicts(d1,d2):
   k1=d1.keys()
   k2=d2.keys()
   unified_dict=dict()
   for k in k1:
       # look up in second dictionary
      if k in k2:
         pt=d2[k]  #pt stands for 'plain text'
         # if lookup is a contradiction, return empty dictionary
         #  don't even bother with partial results
         if pt!=d1[k]:
             return dict()
         else:
             unified_dict[k]=d1[k]  # safe: key is consistent
      else:
          unified_dict[k]=d1[k] # safe:  no key in k2

# get the rest
# already resolved intersection issues so just get set difference
   for k in d2.keys():
      if k not in d1.keys():
          unified_dict[k]=d2[k]

   return unified_dict
Run Code Online (Sandbox Code Playgroud)

有什么改进?

Mar*_*ers 5

在这里使用字典视图 ; 他们让你将字典键视为集合:

def merge_dicts(d1, d2):
    try:
        # Python 2
        intersection = d1.viewkeys() & d2
    except AttributeError:
        intersection = d1.keys() & d2

    if any(d1[shared] != d2[shared] for shared in intersection):
        return {}  # empty result if there are conflicts

    # leave the rest to C code, execute a fast merge using dict()
    return dict(d1, **d2)
Run Code Online (Sandbox Code Playgroud)

上面的代码仅测试引用非匹配值的共享密钥; 合并本身最好留给dict()函数.

我在Python 2和Python 3上都使用了这个函数; 如果您只需要支持其中一个,请删除try..except并替换intersection相关表达式.在Python 3中,该dict.keys()方法默认返回字典视图.

你可以想象这是一个单线; Python 3版本:

def merge_dicts(d1, d2):
    return {} if any(d1[k] != d2[k] for k in d1.keys() & d2) else dict(d1, **d2)
Run Code Online (Sandbox Code Playgroud)

演示:

>>> d1 = {'x': 'a', 'y': 'b', 'z': 'c'}
>>> d2 = {'z': 'c', 'w': 'r'}
>>> d3 = {'z': 'd', 'w': 'r'}
>>> merge_dicts(d1, d2)
{'y': 'b', 'x': 'a', 'z': 'c', 'w': 'r'}
>>> merge_dicts(d1, d3)
{}
>>> merge_dicts(d2, d3)
{}
Run Code Online (Sandbox Code Playgroud)

  • 至于`dict(d1,**d2)`,请参阅[什么做**\*(双星)和\*(星)为Python参数做什么?](http://stackoverflow.com/q/36901)和[`dict()`函数文档](https://docs.python.org/2/library/functions.html#func-dict).`dict(d1)`只创建`d1`的副本.`dict(**d2)`会以圆周的方式创建一个`d2`的副本.`dict(d1,**d2)`创建`d1`的副本,添加`d2`的键值对. (2认同)