【问题标题】:To merge two dictionaries of list in Python在 Python 中合并两个列表字典
【发布时间】:2015-11-26 05:34:59
【问题描述】:

有两个字典

x={1:['a','b','c']}
y={1:['d','e','f'],2:['g']}

我想要另一个字典 z,它是 x 和 y 的合并字典,这样

z = {1:['a','b','c','d','e','f'],2:['g']}

可以做这个操作吗? 我试过更新操作

x.update(y)

但它给了我以下结果

z= {1:['d','e','f'],2:['g']}

【问题讨论】:

    标签: python dictionary


    【解决方案1】:

    一条线解决方案:

    { key:x.get(key,[])+y.get(key,[]) for key in set(list(x.keys())+list(y.keys())) }
    

    示例 1:

    x={1:['a','b','c']}
    y={1:['d','e','f'],2:['g']}
    { key:x.get(key,[])+y.get(key,[]) for key in set(list(x.keys())+list(y.keys())) }
    

    输出:

    {1: ['a', 'b', 'c', 'd', 'e', 'f'], 2: ['g']}

    示例 2:

    one = {'a': [1, 2], 'c': [5, 6], 'b': [3, 4]}
    two = {'a': [2.4, 3.4], 'c': [5.6, 7.6], 'd': [3.5, 4.5]}
    { key:one.get(key,[])+two.get(key,[]) for key in set(list(one.keys())+list(two.keys())) }
    

    输出:

    {'a': [1, 2, 2.4, 3.4], 'b': [3, 4], 'c': [5, 6, 5.6, 7.6], 'd': [3.5, 4.5]}

    【讨论】:

      【解决方案2】:
      for k, v in x.items():
      if k in y.keys():
          y[k] += v
      else:
          y[k] = v
      

      遍历字典获取键和值,检查键是否已经存在,在这种情况下追加,否则添加带有值的新键。如果您的值是不是列表的混合数据类型,它将不起作用,就像您一样。

         x={1:['a','b','c'], 3:['y']} 
      .. y={1:['d','e','f'],2:['g']} 
      ..  
      ..  
      .. for k, v in x.items(): 
      ..     if k in y.keys(): 
      ..         y[k] += v 
      ..     else: 
      ..         y[k] = v 
      ..      
      .. print y
      {1: ['d', 'e', 'f', 'a', 'b', 'c'], 2: ['g'], 3: ['y']}
      

      【讨论】:

        【解决方案3】:

        你可以这样做:

        final = {}
        dicts = [x,y]  # x and y are each dicts defined by op
        
        for D in dicts:
            for key, value in D.items():  # in python 2 use D.iteritems() instead
                final[key] = final.get(key,[]).extend(value)
        

        final.get(key,[]) 将在 final 中获取该键的值(如果存在),否则它将是一个空列表。 .extend(value) 将使用D 中的相应值扩展该列表,无论是否为空,在这种情况下为xy

        【讨论】:

        • 不应该是D.iteritems()吗?
        • @gtangil:我认为这是 Python 2 vs 3 的事情(您的建议是 Python 2 方式)。
        • @El'endiaStarman python 2 是 D.iteritems 是的,但是 python 3 需要 .items()。编辑答案以反映。
        • final.get(key,[]) 不返回空列表,它返回 NoneType 并抛出错误
        【解决方案4】:

        这对我有用:

        d1={'a':[1,2,3], 'b':[4,5,6], 'c':[7,8,9]}
        d2 = {'a':[10,11,12], 'b':[13,14,15], 'c':[16,17,18]}
        d3 = {}
        for k in d1.keys():
            d3.update( {k : []} )
            for i in d1[k]:
                d3[k].append(i)
            for j in d2[k]:
                d3[k].append(j)
        print(d3)
        

        我知道这是一种迂回的方法,但是当字典值为 ndarrays 时,其他方法不起作用。

        【讨论】:

          【解决方案5】:

          这里是任意数量的字典的 Python 3 解决方案:

          def dict_merge(*dicts_list):
              result = {}
              for d in dicts_list:
                  for k, v in d.items():
                      result.setdefault(k, []).append(v)
              return result
          

          请注意,此解决方案可能会创建具有重复值的列表。如果您需要唯一值,请使用set()

          def dict_merge(*dicts_list):
              result = {}
              for d in dicts_list:
                  for k, v in d.items():
                      result.setdefault(k, set()).add(v)
              return result
          

          【讨论】:

            【解决方案6】:

            如果您在项目中选择 Python2.7。在这种情况下可以使用Counter()

            Python 2.7.16 (default, Jun  5 2020, 22:59:21) 
            [GCC 4.2.1 Compatible Apple LLVM 11.0.3 (clang-1103.0.29.20) (-macos10.15-objc- on darwin
            Type "help", "copyright", "credits" or "license" for more information.
            >>> x={1:['a','b','c']}
            >>> y={1:['d','e','f'],2:['g']}
            >>> from collections import Counter
            >>> Counter(x) + Counter(y)
            Counter({2: ['g'], 1: ['a', 'b', 'c', 'd', 'e', 'f']})
            

            在 Python 3.x 中,如果你运行相同的代码,你会看到:

            Python 3.9.0 (v3.9.0:9cf6752276, Oct  5 2020, 11:29:23) 
            Type 'copyright', 'credits' or 'license' for more information
            IPython 7.19.0 -- An enhanced Interactive Python. Type '?' for help.
            
            In [1]: x={1:['a','b','c']}
            
            In [2]: y={1:['d','e','f'],2:['g']}
            
            In [3]: from collections import Counter
            
            In [4]: Counter(x) + Counter(y)
            ---------------------------------------------------------------------------
            TypeError                                 Traceback (most recent call last)
            <ipython-input-4-0aa8b00837b3> in <module>
            ----> 1 Counter(x) + Counter(y)
            
            /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/collections/__init__.py in __add__(self, other)
                759         for elem, count in self.items():
                760             newcount = count + other[elem]
            --> 761             if newcount > 0:
                762                 result[elem] = newcount
                763         for elem, count in other.items():
            
            TypeError: '>' not supported between instances of 'list' and 'int'
            

            我们看一下vim /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/collections/__init__.py +761的源码

            为了检查Python2.x和Python3.x之间的区别,我们将在python2中找到集合的路径。要做到这一点,只需执行一个错误的调用,例如:

            >>> Counter(9,1) # wrong way to call.
            Traceback (most recent call last):
              File "<stdin>", line 1, in <module>
              File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/collections.py", line 475, in __init__
                raise TypeError('expected at most 1 arguments, got %d' % len(args))
            TypeError: expected at most 1 arguments, got 2
            

            然后,您会看到/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/collections.py

            好的,现在打开这两个文件并定位到class Counter 中的__add__ 函数。

            vim -d /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/collections/__init__.py +761 /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/collections.py
            

            但我们可以在这个狙击代码中找到相应的。

            想想这个,你可以看到TypeError: '&gt;' not supported between instances of 'list' and 'int'显示了两个重要的东西:

            • &gt; 反映到class dict 中的def __gt__(self, value, /) 方法。那么让我们来看看python2和python3dict之间的区别。
            • 'list''int'。为了确保我们在这里遇到相同的类型,只需添加一行即可将其打印出来。在这样做之前比较行 if newcount &gt; 0: 像这样:
            print("newcount is --> ", newcount, type(newcount))
            if newcount > 0:
            

            你会看到这个:

            并不奇怪,对吧?我们可以将listint 进行比较,这很有意义..

            让我们在 python 2 中快速比较 listint

            它返回一个True。继续深入Python3.x

            好的,现在您应该清楚发生了什么。要解决这个问题,应该很容易地对您自己的 python 环境进行一些更改或将其提交给git

            最后,您有两个好消息,您修复了 Python3.x 错误。你得到了你的结果。

            如果想要的结果是一个字典。您可以使用以下内容:

            z = dict(Counter(x) + Counter(y))
            

            【讨论】:

            • 请注意,如果字典不相交(即:如果它们不共享一个共同的元素),这将不起作用
            • 我收到了&gt;' not supported between instances of 'list' and 'int'
            • @FrankAK 当你遇到这个错误时,你能扩展一下吗?
            • @nitishagar 已经更新。谢谢你的提醒。
            猜你喜欢
            • 1970-01-01
            • 2013-11-02
            • 1970-01-01
            • 1970-01-01
            • 2016-09-25
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多