__eq__ on a dict

Steven D'Aprano steve at REMOVETHIScyber.com.au
Tue Jul 12 02:37:35 EDT 2005


Replying to myself... how sad.

On Tue, 12 Jul 2005 15:41:46 +1000, Steven D'Aprano wrote:

> That wasn't clear from his post at all. If he had explained what he
> wanted, I wouldn't have wasted my time explaining what he already knew.

On reading it, that came across more snarky than I intended. Sorry.

> Asking the right question helps. But not in this case, because comparison
> of objects is ... confusing. There doesn't seem to be any definitive
> answer to the question, not that I have been able to find, although plenty
> of hints.
> 
> My first thought was the comparisons between dicts is implemented as
> comparisons between their items, ie cmp(dictA, dictB) is turned into
> cmp(dictA.items(), dictB.items()). But that doesn't seem to be the case:

However, I wasn't completely insane, since I came across this tidbit:

http://python.active-venture.com/ref/comparisons.html

"Mappings (dictionaries) compare equal if and only if their sorted (key,
value) lists compare equal. Outcomes other than equality are resolved
consistently, but are not otherwise defined."

with a footnote leading to this comment:

"Earlier versions of Python used lexicographic comparison of the sorted
(key, value) lists, but this was very expensive for the common case of
comparing for equality."

I also suggested:

> My second thought was that comparison is implemented by first comparing
> keys, then values, ie cmp(dictA, dictB)
[snip]
> I don't think I can prove it though.

I certainly can't prove it, since my example pseudo-code fails even on the
example I used earlier. Sigh.

In summary:

Equality of dicts is guaranteed. Two dicts are equal if and only if their
keys:value pairs are equal. Other orderings between dicts are calculated
consistently but not in any documented way.


One gotcha is that some dicts are unordered:

py> {1:1j} < {1:2j}
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: cannot compare complex numbers using <, <=, >, >=

but even that is special-cased up to the wazzoo:

py> {1:1j} < {1:1j}
False

-- 
Steven.




More information about the Python-list mailing list