473,397 Members | 1,950 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

__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 14207
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Shane Hathaway | last post by:
I was surprised by the following behavior. Apparently, the "!=" operator does not fall back to using "not __eq__()". I tested this with Python 2.1, 2.2, and 2.2 with new-style classes and got the...
9
by: Robin Cull | last post by:
Imagine I have a dict looking something like this: myDict = {"key 1": , "key 2": , "key 3": , "key 4": } That is, a set of keys which have a variable length list of associated values after...
31
by: John Roth | last post by:
I'm adding a thread for comments on Gerrit Holl's pre-pep, which can be found here: http://tinyurl.com/2578q Frankly, I like the idea. It's about time that all of the file and directory stuff...
1
by: David Vaughan | last post by:
I was expecting the class sets.Set to act like an unordered list with no two members equal. But, while the following code prints True, the assertion fails. from sets import Set _base = str...
49
by: Steven Bethard | last post by:
I promised I'd put together a PEP for a 'generic object' data type for Python 2.5 that allows one to replace __getitem__ style access with dotted-attribute style access (without declaring another...
3
by: Bengt Richter | last post by:
Has anyone found a way besides not deriving from dict? Shouldn't there be a way? TIA (need this for what I hope is an improvement on the Larosa/Foord OrderedDict ;-) I guess I can just document...
11
by: sandravandale | last post by:
I can think of several messy ways of making a dict that sets a flag if it's been altered, but I have a hunch that experienced python programmers would probably have an easier (well maybe more...
15
by: George Sakkis | last post by:
Although I consider dict(**kwds) as one of the few unfortunate design choices in python since it prevents the future addition of useful keyword arguments (e.g a default value or an orderby...
12
by: jeremito | last post by:
Please excuse me if this is obvious to others, but I can't figure it out. I am subclassing dict, but want to prevent direct changing of some key/value pairs. For this I thought I should override...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.