470,631 Members | 1,622 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,631 developers. It's quick & easy.

__eq__ on a dict

Hello,

I can't find the docs for __eq__ on a dict and I can't find
a description on what the eq does (strangely it does implement > and <
but I have no idea what that does). Does anyone know (definitively)
what the __eq__, __gt__, __lt__ methods do.

BTW, google is not my friend - I invited it out for a drink last
week and it stood me up :-).

Cheers,

Neil

--

Neil Benn
Senior Automation Engineer
Cenix BioScience
BioInnovations Zentrum
Tatzberg 46
D-01307
Dresden
Germany

Tel : +49 (0)351 4173 154
e-mail : be**@cenix-bioscience.com
Cenix Website : http://www.cenix-bioscience.com

Jul 21 '05 #1
9 13167
These methods are documanted here:
http://docs.python.org/ref/customization.html

Jul 21 '05 #2
On Mon, 11 Jul 2005 12:42:55 +0200, Neil Benn wrote:
Hello,

I can't find the docs for __eq__ on a dict and I can't find
a description on what the eq does (strangely it does implement > and <
but I have no idea what that does). Does anyone know (definitively)
what the __eq__, __gt__, __lt__ methods do.

BTW, google is not my friend - I invited it out for a drink last
week and it stood me up :-).


It works for me. Google on "__eq__ Python" and the 5th and 6th sites are:

http://python.active-venture.com/ref/customization.html
http://www.network-theory.co.uk/docs/pylang/ref_32.html

Normally, asking Python for help is a good way to read the docs, but in
this particular case, it is a big let-down:

py> help({}.__eq__)
Help on method-wrapper:

__eq__ = <method-wrapper object>
For any two objects x and y, when you call

x == y

Python calls x.__eq__(y). That includes dicts:

py> dictA = {0: "spam"}
py> dictB = {0: "sp" + "am"}
py> dictC = {1: "ham"}
py>
py> dictA == dictB
True
py> dictA.__eq__(dictB) # same as dictA == dictB
True
py> dictB == dictC # calls dictB.__eq__(dictC)
False

Two dicts are equal if they have the same keys and the same values.

In general, you should not call __eq__ directly, but use the == operator
instead.

Likewise:

x > y becomes x.__gt__(y)
x < y becomes x.__lt__(y)
x >= y becomes x.__ge__(y)
x <= y becomes x.__le__(y)
x != y becomes x.__ne__(y)
x <> y also becomes x.__ne__(y)
--
Steven

Jul 21 '05 #3
wi******@hotmail.com wrote:
These methods are documanted here:
http://docs.python.org/ref/customization.html

Hmm, can't see anything about implementation of python dict methods
__eq__, __lt__ or __gt__ there - general docs but not specific to the
dict here - at least not as far as I can see from these docs.

Neil

--

Neil Benn
Senior Automation Engineer
Cenix BioScience
BioInnovations Zentrum
Tatzberg 46
D-01307
Dresden
Germany

Tel : +49 (0)351 4173 154
e-mail : be**@cenix-bioscience.com
Cenix Website : http://www.cenix-bioscience.com

Jul 21 '05 #4
"Steven D'Aprano" <st***@REMOVETHIScyber.com.au> writes:
On Mon, 11 Jul 2005 12:42:55 +0200, Neil Benn wrote:
Hello,

I can't find the docs for __eq__ on a dict and I can't find
a description on what the eq does (strangely it does implement > and <
but I have no idea what that does). Does anyone know (definitively)
what the __eq__, __gt__, __lt__ methods do.

[snip]
For any two objects x and y, when you call

x == y

Python calls x.__eq__(y). That includes dicts:

py> dictA = {0: "spam"}
py> dictB = {0: "sp" + "am"}
py> dictC = {1: "ham"}
py>
py> dictA == dictB
True
py> dictA.__eq__(dictB) # same as dictA == dictB
True
py> dictB == dictC # calls dictB.__eq__(dictC)
False

Two dicts are equal if they have the same keys and the same values.
That is what I would expect, but where is that documented? Also,
where is the behavior of the much less obvious dictionary methods
__ge__, __gt__, __le__, __lt__, and __cmp__ methods documented?
In general, you should not call __eq__ directly, but use the == operator
instead.


That is clear enough, the OP was seeking information about the
behavior of these operators when used with dictionaries.

Thanks,

--
--------------------------------------------------------------------
Aaron Bingham
Senior Software Engineer
Cenix BioScience GmbH
--------------------------------------------------------------------

Jul 21 '05 #5
Steven D'Aprano wrote:
On Mon, 11 Jul 2005 12:42:55 +0200, Neil Benn wrote:
Hello,

I can't find the docs for __eq__ on a dict and I can't
find a description on what the eq does (strangely it does implement >
and < but I have no idea what that does). Does anyone know
(definitively) what the __eq__, __gt__, __lt__ methods do.

BTW, google is not my friend - I invited it out for a drink last
week and it stood me up :-) .
It works for me. Google on "__eq__ Python" and the 5th and 6th sites are:

http://python.active-venture.com/ref/customization.html
http://www.network-theory.co.uk/docs/pylang/ref_32.html

<snip>
As previous reply
Normally, asking Python for help is a good way to read the docs, but in
this particular case, it is a big let-down:

py> help({}.__eq__)
Help on method-wrapper:

__eq__ = <method-wrapper object>
For any two objects x and y, when you call
x == y

<snip>

<snip>
That's the empirical evidence that I got but I want to be 100% sure that
this holds in all cases - I'm wary about using empirical evidence
leading to assumptions in my code - I take the paradigm that 'Assumption
is the mother of all f**k-ups'.
In general, you should not call __eq__ directly, but use the == operator
instead.

<snip>
Yeah I'm aware of that, I didn't want to start talking about ==, etc
or I may mislead people into the - this is what __eq__ means path of
explanation.

Thanks for your response.

Neil

--

Neil Benn
Senior Automation Engineer
Cenix BioScience
BioInnovations Zentrum
Tatzberg 46
D-01307
Dresden
Germany

Tel : +49 (0)351 4173 154
e-mail : be**@cenix-bioscience.com
Cenix Website : http://www.cenix-bioscience.com

Jul 21 '05 #6
On Mon, 11 Jul 2005 13:54:05 +0200, Aaron Bingham wrote:
Two dicts are equal if they have the same keys and the same values.


That is what I would expect, but where is that documented? Also,
where is the behavior of the much less obvious dictionary methods
__ge__, __gt__, __le__, __lt__, and __cmp__ methods documented?
In general, you should not call __eq__ directly, but use the == operator
instead.


That is clear enough, the OP was seeking information about the
behavior of these operators when used with dictionaries.


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.

You know, something like "I already know that __eq__ is equivalent to ==,
likewise for the other operators > etc, what I want to know is how are
equality, less than, greater than, etc implemented specifically for dicts."

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:

py> dictA = {None: None, 1:1}
py> dictB = {1: 1}
py> cmp(dictA, dictB)
1
py> cmp(dictA.items(), dictB.items())
-1

My second thought was that comparison is implemented by first comparing
keys, then values, ie cmp(dictA, dictB) turns into:

order = cmp(dictA.keys(), dictB.keys())
if order == 0: # keys are equal
order = cmp(dictA.values(), dictB.values())
return order

I don't think I can prove it though.
--
Steven.

Jul 21 '05 #8
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.

Jul 21 '05 #9
Hi Steven,

Thanks for digging into this.

"Steven D'Aprano" <st***@REMOVETHIScyber.com.au> writes:
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.


It's ok. I realize the OP did not make it crystal clear what he was
getting at in his post. It's easier when you are sitting in the same
office ;-).
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."
Ah, I missed that, thanks for the pointer. Seems information of
dictionary comparisons should also appear in the Library Reference
under Mapping Types.
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.


Looking at the source code links Simon posted (thanks Simon!) it is
clear that, in the current version of CPython, dictionaries are
ordered first by length and only if the lengths are equal are the
keys and values examined.
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


Hmm... not sure I like that!

--
--------------------------------------------------------------------
Aaron Bingham
Senior Software Engineer
Cenix BioScience GmbH
--------------------------------------------------------------------

Jul 21 '05 #10

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

reply views Thread by Shane Hathaway | last post: by
9 posts views Thread by Robin Cull | last post: by
31 posts views Thread by John Roth | last post: by
1 post views Thread by David Vaughan | last post: by
49 posts views Thread by Steven Bethard | last post: by
15 posts views Thread by George Sakkis | last post: by
12 posts views Thread by jeremito | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.