查找两个词典的匹配键值对

时间:2014-02-07 15:44:00

标签: python

检查一个字典的键值对是否也出现在其他字典中的最有效方法是什么。
假设我有两个词典 dict1 dict2 ,这两个词典有一些共同的键值对。我想找到那些并打印出来。最有效的方法是什么?请建议。

4 个答案:

答案 0 :(得分:9)

一种方式是:

d_inter = dict([k, v for k, v in dict1.iteritems() if k in dict2 and dict2[k] == v])

另一个:

d_inter = dict(set(d1.iteritems()).intersection(d2.iteritems()))

我不确定哪一个会更有效率,所以让我们比较两者:

1。通过dicts迭代的解决方案:

  • 我们解析了dict1的所有键:for k,v in dict1.iteritems() - > O(n)
  • 然后我们检查密钥是否在dict2中,if k in dict2 and dict2[k] == v - > O(M)

这使其成为O(n+m) - >的全球最坏情况复杂性O(n)

2。解决方案set s:

如果我们假设将dict转换为集合O(n)

  • 我们解析d1的所有项目以创建第一组set(d1.iteritems()) - > O(n)
  • 我们解析d2的所有项目以创建第二组set(d2.iteritems()) - > O(m)
  • 我们得到两者的交叉点,平均为O(min(len(s), len(t))或在最坏的情况下为O(n * m)

这使得O(2n*n*m)的全局最坏情况复杂度对于相同大小的dicts可以被视为O(n^3):那么解决方案1.是最好的

如果我们假设将dict转换为集合为O(1)(常量时间)

平均值为O(min(n,m)),最差情况为O(n*m),因此解决方案#1在最差情况下效果最佳,但解决方案#2在平均情况下最佳,因为O(n+m) > O(min(n,m))

总之,您选择的解决方案取决于您的数据集和您将进行的测量! ; - )

N.B。:我把there的复杂性放在了集合()。

N.B.2:对于解决方案#1,始终将最小的dict设为dict2,对于解#2,将最小的dict设为dict1


N.B.2016:此解决方案是为 python2 编写的。以下是使 python3 准备就绪所需的更改:

  • iteritems()替换为items();
  • 您还可以使用较新的字典理解语法:{[k, v for … == v]};
  • d.items()返回dict_items时不再可以播放,您必须使用frozenset()代替{frozenset(d1.items()).intersection(d2.items())}

答案 1 :(得分:2)

怎么样......

matching_dict_values = {}
for key in dict1.keys():
    if key in dict2.keys():
        if dict1[key] == dict2[key]:
            matching_dict_values[key]=dict1[key]

答案 2 :(得分:0)

我不明白为什么你需要比这更漂亮的东西:

if all([testKey in dict1, testKey in dict2]) and dict1[testKey] == dict2[testKey]:

我们不必担心KeyError,因为布尔测试将在and之前失败(做一个与其中一个不相关的键相关的值永远不会得到测试)

因此,要获得完整列表的公共键值对,您可以这样做:

for testKey in set(dict1.keys() + dict2.keys()):
    if all([testKey in dict1, testKey in dict2]) and dict1[testKey] == dict2[testKey]:
        commonDict[testKey] = dict1[testKey]

答案 3 :(得分:0)

更新@zmo 的回答

解决方案 1:

d_inter = {k:v for k, v in dict1.items() if k in dict2 and dict2[k] == v}

解决方案 2:

d_inter = dict(set(dict1.items()).intersection(dict2.items()))