Python 查找两个字典的匹配键值对
检查一个字典的键值对是否也存在于另一个字典中的最有效方法是什么。Python 查找两个字典的匹配键值对,python,Python,检查一个字典的键值对是否也存在于另一个字典中的最有效方法是什么。假设我有两个字典,如dict1和dict2,这两个字典有一些相同的键值对。我想找到并打印出来。最有效的方法是什么?请建议。我不明白你为什么需要比这更华丽的东西: if all([testKey in dict1, testKey in dict2]) and dict1[testKey] == dict2[testKey]: 我们不必担心键错误,因为在和之前,布尔测试将失败(如果某个值与不在其中一个值中的键相关,则永远不会进行测试
假设我有两个字典,如dict1和dict2,这两个字典有一些相同的键值对。我想找到并打印出来。最有效的方法是什么?请建议。我不明白你为什么需要比这更华丽的东西:
if all([testKey in dict1, testKey in dict2]) and dict1[testKey] == dict2[testKey]:
我们不必担心键错误
,因为在和
之前,布尔测试将失败(如果某个值与不在其中一个值中的键相关,则永远不会进行测试)
因此,要获得完整的公共键值对列表,可以执行以下操作:
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]
一种方法是:
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.iteritems()中的k,v解析dict1:
的所有键
- 然后我们检查键是否在dict2中,
->O(m)如果dict2中的k和dict2[k]==v
O(n+m)
->O(n)
2.设置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)
,对于相同大小的dict,可以将其视为O(n^3
):那么解决方案1.是最好的
如果我们假设将一个dict
转换成一个集合是O(1)
(恒定时间)
平均值为O(min(n,m))
最坏情况为O(n*m)
,那么解决方案1在最坏情况下是最好的,而解决方案2在平均情况下是最好的,因为O(n+m)>O(min(n,m))
总之,您选择的解决方案将取决于您的数据集和您将进行的测量!;-)
注:我考虑了集合的复杂性()
注意2:对于解决方案,1始终将最小的dict设置为dict2
,对于解决方案,2始终将最小的dict设置为dict1
注意:2016年:该解决方案是为python2编写的。以下是使python3准备就绪所需的更改:
- 将
iteritems()
替换为items()
李>
- 您还可以使用较新的dict理解语法:
{[k,v for…==v]}
李>
- 由于
d.items()
返回不再可散列的dict\u items
,因此必须使用frozenset()
来代替{frozenset(d1.items()).intersection(d2.items())}
那么
matching_dict_values = {}
for key in dict1.keys():
if key in dict2.keys():
if dict1[key] == dict2[key]:
matching_dict_values[key]=dict1[key]
更新@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()))
他想要的是两个dict的交集,而不是给定的键是否在两个dict中。因此,要将您的解决方案应用于他的问题,您应该告诉他在dict1.keys()+dict2.keys()中对testKey执行:…
@zmo,在我看来,这里真正的问题是找到一个键值对是否对两者都是公共的,之后的一切都相当简单,但我会更新以获得一个公共对的完整列表即使你的问题回答了这个问题,它也没有效率,因为它意味着一个常量O(n*m*(n+m))
,即O(n3)
在最坏的情况下。在我的本地测试中,比较:2.86 us/循环
并设置:2.06 us/循环
。所以set
更好(至少对于小型词典是这样)+1set+iteritems
usage@FallenAngel:谢谢你的统计数据!您可以使用dict2中的k来加快第一种方法的速度;在Python 2中,dict2.keys()
中的k首先创建一个列表,然后必须对其进行扫描…这在算法中添加了一个不必要的O(m)
@DSM很高兴知道,我一直认为两者是等效的,因此更喜欢使用.keys()
作为“显式优于隐式”:-)这是因为不能使用列表作为键!每个设计的列表都是可变的,因此不可能计算用于密钥比较的哈希。如果您确实需要某种列表作为键(这是一种设计选择,在实现之前您确实需要三思而后行),您最好使用tuple()
。这与我的解决方案#1相同,但不是作为一行。您知道其中一行是否比另一行更有效吗?您的意思是什么?是的,我知道,实际上我的解决方案#1比你的解决方案好,因为我使用的是.iteritems()
,并且我按照@DSM的建议不要使用.keys()
。有关所有细节,请参阅我的答案。