Reputation: 113
I came across this:
>>> d1 = {"john":40, "peter":45}
>>> d2 = {"john":466, "peter":45}
>>> d1 > d2
False
What does the comparison operator do while comparing two dicts and how does it output False
?
Upvotes: 3
Views: 3548
Reputation: 363043
Since these dicts have equal length, we find the smallest key for which the corresponding values are unequal, i.e. 'john'
. Then the dicts are compared on the value of that key.
Demo:
>>> d1 = {"john":40, "peter":45}
>>> d2 = {"john":466, "peter":45}
>>> d1 < d2
True
>>> d2['john'] = 39
>>> d1 < d2
False
This basic idea is essentially unchanged since Guido's commit from over 20 years ago:
$ git show a0a69b8
commit a0a69b8b429f3d4c91f1c432247cfda017505976
Author: Guido van Rossum <[email protected]>
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).
It is not documented, and the dict comparison code is removed in Python 3, so I wouldn't rely on that for anything important. The relevant CPython source is here.
Fun fact: Apparently, in older versions of Python, some dict comparisons could crash the runtime and could even cause Windows 98 to reboot. Heh.
Upvotes: 8
Reputation: 2652
Dictionaries, like sets, do not maintain a well-defined order on their elements. Furthermore, the concept of a subset is not typically meaningful for dictionaries, so the dict class does not support operators such as
<
. Dictionaries support the notion of equivalence, with d1 == d2 if the two dictionaries contain the same set of key- value pairs.
So what you can do is,
d1 == d2 #d1 is equivalent to d2
d1 != d2 #d1 is not equivalent to d2
However you cannot do > < >= <=
This is in 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()
>>>
However in python 2 take a look at this,
>>> a = {2:2}
>>> b = {2:2}
>>> a==b
True
>>> a<b
False
>>> a>b
False
But when the key
is same and value
is different
>>> a={3:1}
>>> b={3:2}
>>> a<b
True
>>> a>b
False
Again if value
is same,
>>> a={3:0}
>>> b={3:0}
>>> a==b
True
>>> a<b
False
>>> a>b
False
But notice this when value in first dict
is greater
>>> a={3:200}
>>> b={3:10}
>>> a<b
False
>>> a>b
True
Till now we had same key
different values
now let's change that,
Now Same value different key
>>> a={2:10}
>>> b={3:10}
>>> a<b
True
>>> a>b
False
>>>
>>> a={10:10}
>>> b={1:10}
>>> a<b
False
>>> a>b
True
What can you get from this, Python 2 either key is checked and if it's same, only then ,value is checked. Now let's have different key , different values,
>>> a={10:10}
>>> b={1:100}
>>> a<b
False
>>> a>b
True
Aha! In this case you can infer that key
is the first thing that will be checked and if they are the same only then value will be checked. Now let's say we have more than one key:value
pair in our dictionary?
>>> 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
So it means. Every key
is checked and then if key
is same value will be checked. Ah but how does key checking work ? For that take a look at dict_compare source code
NOTE: The method cmp() returns the sign of the difference of two numbers : -1 if x < y, 0 if x == y, or 1 if x > y
So basically What happens is that to compare dicts A and B, lengths are compared first (equal no problem). If they are unequal, then return cmp(len(A), len(B)).
Next, find the key akey
in A that is the smallest key for which
akey not in B or
A[akey] != B[akey]
-->(This happens only when akey is present in B).
(If there is no such key, the dicts are equal.)
Also (must) find the smallest key bkey in B for which
bkey not in A
or A[bkey] != B[bkey]
-->(This happens only when bkey is present in B).
If akey != bkey, then return cmp(akey, bkey). Else return 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
So the smallest key in A
not in B
is 200
similarly 1
in A
.
Now internaly python compares them according to the given above algorithm so cmp(200,1)
would be calculated when a>b
is done. Else cmp(1,200)
if a<b
is done.
But this was removed completely from python 3. This doesn't work in python 3.
Upvotes: 2
Reputation: 11
>>> d2>d1
True
>>> d3 = {"john":40, "peter":45}
>>> d1>=d3
True
As you can see above, comparison on dictionaries done by key. These are equals;
>>> res = []
>>> for key1,val1 in d1.iteritems():
... res.append(val1 >d2[key1] )
>>> res
[False, False]
>>> all(res)
False
>>> d1 > d2
False
Upvotes: -1