【问题标题】:Find common members that are in two lists of dictionaries查找两个字典列表中的共同成员
【发布时间】:2015-03-26 03:50:32
【问题描述】:

这可能是重复的,但我能找到的最接近的是 Comparing 2 lists consisting of dictionaries with unique keys in python,它对我不起作用。

所以我有两个字典列表。

y = [{'a': 3, 'b': 4, 'c': 5}, {'a': 1, 'b': 2, 'c': 3}]
y = [{'a': 4, 'b': 5, 'c': 6}, {'a': 1, 'b': 2, 'c': 3}]

如何比较这两个列表,以便我的比较结果是两个列表的交集。我无法将其转换为 set,因为它说的是不可散列类型(dict)

【问题讨论】:

  • 在确定交点时要考虑什么?按键?价值?键/值对?
  • 从问题来看,他的意思好像是键值对。
  • 预期输出是什么?
  • 而你如何定义这样一个“交叉点”?

标签: python dictionary


【解决方案1】:

您的问题和标题似乎不一致。

两个列表的交集将是两个列表的共同元素。问题标题请求两个列表中 not 的元素。你想要哪个?

对于交集,效率不是很高(时间为 O(n^2)),但是这个列表推导会做到:

>>> a = [{'a': 3, 'b': 4, 'c': 5}, {'a': 1, 'b': 2, 'c': 3}]
>>> b = [{'a': 4, 'b': 5, 'c': 6}, {'a': 1, 'b': 2, 'c': 3}]
>>> [d for d in a if d in b]
[{'a': 1, 'b': 2, 'c': 3}]

【讨论】:

    【解决方案2】:
    y1 = [{'a': 3, 'b': 4, 'c': 5}, {'a': 1, 'b': 2, 'c': 3}]
    y2 = [{'a': 4, 'b': 5, 'c': 6}, {'a': 1, 'b': 2, 'c': 3}]
    print [x for x in y1 if x in y2] # prints [{'a': 1, 'c': 3, 'b': 2}]
    

    【讨论】:

      【解决方案3】:

      一个字典(或列表)是不可散列的,但是,一个元组是。您可以将字典列表转换为一组元组。执行交集,然后转换回来

      转换为元组集的代码

      y_tupleset = set(tuple(sorted(d.items())) for d in y)
      

      将相交的元组集转换回字典列表的代码

      y_dictlist = [dict(it) for it in list(y_tupleset)]
      

      因此,完整的代码是:

      y0 = [{'a': 3, 'b': 4, 'c': 5}, {'a': 1, 'b': 2, 'c': 3}]
      y1 = [{'a': 4, 'b': 5, 'c': 6}, {'a': 1, 'b': 2, 'c': 3}]
      
      y0_tupleset = set(tuple(sorted(d.items())) for d in y0)
      y1_tupleset = set(tuple(sorted(d.items())) for d in y1)
      y_inter = y0_tupleset.intersection(y1_tupleset)
      y_inter_dictlist = [dict(it) for it in list(y_inter)]
      
      print(y_inter_dictlist)
      # prints the following line
      [{'a': 1, 'c': 3, 'b': 2}]
      

      编辑:d.items() 在 python3 上有效,对于 python2,应替换为 d.iteritems()

      【讨论】:

        【解决方案4】:

        选择你的毒药:

        y1 = [{'a': 3, 'b': 4, 'c': 5}, {'a': 1, 'b': 2, 'c': 3}]
        y2 = [{'a': 4, 'b': 5, 'c': 6}, {'a': 1, 'b': 2, 'c': 3}]
        y3 = [{'a': 1, 'b': 2, 'c': 3}, {'a': 4, 'b': 2, 'c': 6}]
        
        # Returns a list of keys that are in both dictionaries
        def intersect_keys(d1, d2):
            return [k for k in d1 if k in d2]
        
        # Returns a list of values that are in both dictionaries
        def intersect_vals(d1, d2):
            return [v for v in d1.itervalues() if v in d2.itervalues()]
        
        # Returns a list of (key,value) pairs that are in both dictionaries
        def intersect_pairs(d1, d2):
            return [(k,v) for (k,v) in d1.iteritems() if k in d2 and d2[k] == v]
        
        
        print(intersect_keys(*y1))      # ['a', 'c', 'b']
        print(intersect_vals(*y1))      # [3]
        print(intersect_pairs(*y1))     # []
        
        print(intersect_keys(*y2))      # ['a', 'c', 'b']
        print(intersect_vals(*y2))      # []
        print(intersect_pairs(*y2))     # []
        
        print(intersect_keys(*y3))      # ['a', 'c', 'b']
        print(intersect_vals(*y3))      # [2]
        print(intersect_pairs(*y3))     # [('b', 2)]
        

        注意:这些示例比较了y* 列表的两个元素,这就是我解释您的问题的方式。你当然可以使用类似的东西:

        print(intersect_pairs(y1[0], y2[0]))
        

        要计算y1y2 列表中的第一个字典的交集。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-01-07
          • 2017-01-31
          • 1970-01-01
          • 2021-01-01
          相关资源
          最近更新 更多