Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 查找两个字典的匹配键值对_Python - Fatal编程技术网

Python 查找两个字典的匹配键值对

Python 查找两个字典的匹配键值对,python,Python,检查一个字典的键值对是否也存在于另一个字典中的最有效方法是什么。假设我有两个字典,如dict1和dict2,这两个字典有一些相同的键值对。我想找到并打印出来。最有效的方法是什么?请建议。我不明白你为什么需要比这更华丽的东西: if all([testKey in dict1, testKey in dict2]) and dict1[testKey] == dict2[testKey]: 我们不必担心键错误,因为在和之前,布尔测试将失败(如果某个值与不在其中一个值中的键相关,则永远不会进行测试

检查一个字典的键值对是否也存在于另一个字典中的最有效方法是什么。
假设我有两个字典,如dict1dict2,这两个字典有一些相同的键值对。我想找到并打印出来。最有效的方法是什么?请建议。

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

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中,
    如果dict2中的k和dict2[k]==v
    ->O(m)
这使得它成为一个全局最坏情况复杂性
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
      更好(至少对于小型词典是这样)+1
      set+iteritems
      usage@FallenAngel:谢谢你的统计数据!您可以使用dict2中的
      k来加快第一种方法的速度;在Python 2中,dict2.keys()
      中的
      k首先创建一个列表,然后必须对其进行扫描…这在算法中添加了一个不必要的
      O(m)
      @DSM很高兴知道,我一直认为两者是等效的,因此更喜欢使用
      .keys()
      作为“显式优于隐式”:-)这是因为不能使用列表作为键!每个设计的列表都是可变的,因此不可能计算用于密钥比较的哈希。如果您确实需要某种列表作为键(这是一种设计选择,在实现之前您确实需要三思而后行),您最好使用
      tuple()
      。这与我的解决方案#1相同,但不是作为一行。您知道其中一行是否比另一行更有效吗?您的意思是什么?是的,我知道,实际上我的解决方案#1比你的解决方案好,因为我使用的是
      .iteritems()
      ,并且我按照@DSM的建议不要使用
      .keys()
      。有关所有细节,请参阅我的答案。