比较运算符在字典上做了什么?

时间:2017-06-27 04:26:04

标签: python python-2.7 dictionary

我遇到了这个:

>>> d1 = {"john":40, "peter":45}
>>> d2 = {"john":466, "peter":45}
>>> d1 > d2
False

比较算子在比较两个dicts时做了什么以及如何输出False

3 个答案:

答案 0 :(得分:5)

由于这些dicts长度相等,我们找到相应值不相等的最小密钥,即'john'。然后将该词与该键的值进行比较。

演示:

>>> d1 = {"john":40, "peter":45}
>>> d2 = {"john":466, "peter":45}
>>> d1 < d2
True
>>> d2['john'] = 39
>>> d1 < d2
False

这个基本思想从20多年前的Guido's commit开始基本没有变化:

$ git show a0a69b8
commit a0a69b8b429f3d4c91f1c432247cfda017505976
Author: Guido van Rossum <guido@python.org>
Date:   Thu Dec 5 21:55:55 1996 +0000

    Experimental new implementation of dictionary comparison.  This
    defines that a shorter dictionary is always smaller than a longer one.
    For dictionaries of the same size, the smallest differing element
    determines the outcome (which yields the same results as before,
    without explicit sorting).

没有记录,并且在Python 3中删除了dict比较代码,所以我不会依赖于那些重要的东西。相关的CPython源是here

有趣的事实:显然,在旧版本的Python中,某些字典比较可能会使运行时崩溃,甚至可能cause Windows 98 to reboot。嘿。

答案 1 :(得分:1)

  

字典与集合一样,不会在元素上保持明确的顺序。   此外,子集的概念通常对字典没有意义,因此   该   字典   class不支持运算符   <   。字典支持这一概念   等价的,与   d1 == d2   如果这两个字典包含相同的密钥集 -   价值对。

所以你可以做的是,

d1 == d2  #d1 is equivalent to d2
d1 != d2  #d1 is not equivalent to d2

但是你不能> < >= <=

这是在python 3中。

>>> a
{1: '1', 2: '2'}
>>> b
{1: '1', 2: '2'}
>>> a==b
True
>>> a<b
Traceback (most recent call last):
  File "<pyshell#31>", line 1, in <module>
    a<b
TypeError: unorderable types: dict() < dict()
>>> a>b
Traceback (most recent call last):
  File "<pyshell#32>", line 1, in <module>
    a>b
TypeError: unorderable types: dict() > dict()
>>> 

然而在python 2中看看这个,

>>> a = {2:2}
>>> b = {2:2}
>>> a==b
True
>>> a<b
False
>>> a>b
False

但是当key相同且value不同时

>>> a={3:1}
>>> b={3:2}
>>> a<b
True
>>> a>b
False

如果value相同,

>>> a={3:0}
>>> b={3:0}
>>> a==b
True
>>> a<b
False
>>> a>b
False

但是,当第一个dict中的值更大时,请注意这一点

>>> a={3:200}
>>> b={3:10}
>>> a<b
False
>>> a>b
True

直到现在我们有key个不同的values现在让我们改变它,

现在相同值不同的密钥

>>> a={2:10}
>>> b={3:10}
>>> a<b
True
>>> a>b
False
>>> 
>>> a={10:10}
>>> b={1:10}
>>> a<b
False
>>> a>b
True

从中可以得到什么,Python 2中的任一项都经过检查,如果相同,只有,则会检查值。现在让我们有不同的关键,​​不同的值,

>>> a={10:10}
>>> b={1:100}
>>> a<b
False
>>> a>b
True

啊哈!在这种情况下,您可以推断key是第一个要检查的内容,如果它们只相同,那么将检查值。现在假设我们的字典中有多个key:value对?

>>> a={10:10,1:10}
>>> b={10:10,2:10}
>>> a<b
True
>>> a>b
False
>>> a={10:10,200:10}
>>> b={10:10,1:10}
>>> a<b
False
>>> a>b
True

所以这意味着。检查每个key,然后检查key是否相同。啊,但密钥检查如何工作?为此,请查看dict_compare source code

注意:方法cmp()返回两个数字差异的符号:-1如果x&lt; y,如果x == y,则为0;如果x>,则为1。 ÿ

所以基本上会发生什么,比较词组A和B,首先比较长度(相同没问题)。如果它们不相等,则返回cmp(len(A),len(B))。

接下来,找到A中的键akey,该键是

的最小键

akey not in B or A[akey] != B[akey] - &gt;(仅当B中存在akey时才会发生这种情况。)

(如果没有这样的密钥,则表示相同。)

同样(必须)找到B中

的最小键bkey

bkey not in A  或A[bkey] != B[bkey] - &gt;(仅当B中存在bkey时才会发生这种情况。)

如果akey!= bkey,则返回cmp(akey,bkey)。否则返回cmp(A [akey],B [bkey])

>>> a={10:10,200:10}
>>> b={10:10,1:10}
>>> a<b
False
>>> a>b
True
>>> cmp(200,1)
1
>>> cmp(1,200)
-1

因此A中不在B中的最小键2001中的A类似{/ 1}}。

现在,internaly python根据上面给出的算法对它们进行比较,以便在cmp(200,1)完成时计算a>b。如果cmp(1,200)完成,则a<b

但是这完全从python 3中删除了。这在python 3中不起作用。

答案 2 :(得分:-1)

>>> d2>d1
True
>>> d3 = {"john":40, "peter":45}
>>> d1>=d3
True

正如您在上面所看到的,对按键完成的词典进行比较。这些是等于;

>>> res = []
>>> for key1,val1 in d1.iteritems():
...     res.append(val1 >d2[key1] )
>>> res
[False, False]
>>> all(res)
False
>>> d1 > d2
False