[Patches] [ python-Patches-421922 ] Restrict dict comparison to Py_EQ
noreply@sourceforge.net
noreply@sourceforge.net
Mon, 07 May 2001 11:26:22 -0700
Patches item #421922, was updated on 2001-05-06 20:10
You can respond by visiting:
http://sourceforge.net/tracker/?func=detail&atid=305470&aid=421922&group_id=5470
Category: core (C code)
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: Tim Peters (tim_one)
Assigned to: Guido van Rossum (gvanrossum)
Summary: Restrict dict comparison to Py_EQ
Initial Comment:
Dict comparison currently requires that the keys and
values enjoy a total ordering, but dicts only require
Py_EQ in other contexts. The patch changes dict
compares to rely on just Py_EQ too, and replaces the
cmp()-like calls with comparison of raw object
addresses. Besides yielding a huge speedup on an
artificial test case <wink>, it stops surprises like
these:
>>> {1: 1j} == {1: 2j}
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: cannot compare complex numbers using <, <=,
>, >=
>>> {1j: 0} == {2j: 0}
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: cannot compare complex numbers using <, <=,
>, >=
>>>
After the patch:
>>> {1: 1j} == {1: 2j}
0
>>> {1j: 0} == {2j: 0}
0
>>> cmp({1: 1j}, {1: 1j})
0
>>> cmp({1j: 0}, {1j: 0})
0
>>>
----------------------------------------------------------------------
>Comment By: Tim Peters (tim_one)
Date: 2001-05-07 11:26
Message:
Logged In: YES
user_id=31435
Ya, this patch is dead.
WRT A<B and C>D while A==C and B==D, yes, I'm afraid that's
possible, and that sucks bigtime. The underlying problem
is that I see no practical way to extend an equality
relation (given by Py_EQ) to a total ordering. For
example, if "==" is determined by Py_EQ, and "<" by address
comparison, then (forget dicts here for the moment) we can
construct A, B1 and B2 s.t.
A < B1 == B2 < A
Then using those as keys and/or values in dicts can lead to
inconsistent dict comparisons too (with this patch applied).
I had three use cases in mind:
1. Speed (in)equality testing. A note Greg Wilson sent
earlier this year reminded me that this is an important
operation for sets (which he's implementing on top of
dicts).
2. Ensure that (in)equality testing of dicts doesn't blow
up just because the keys and/or values support only a
partial ordering, or only (in)equality testing (complex
numbers are just an extreme case of this).
3. Support sorting a list of dicts without blowing up,
again if the keys and/or values support only a partial
ordering.
I've given up on #3. #1 and #2 could be accomplished by
implementing the tp_richcompare slot for dicts instead: if
I know up-front that "equal: yes or no?" is the only
outcome of interest, then a different, simpler and faster
algorithm using only Py_EQ on keys and values would suffice.
----------------------------------------------------------------------
Comment By: Guido van Rossum (gvanrossum)
Date: 2001-05-07 06:17
Message:
Logged In: YES
user_id=6380
I have one question about this. Will the comparison between
dicts using cmp() or <, <=, >, >= also depend on the raw
object address? That would mean that (even in one program)
there could be two pairs of dictionaries (A,B) and (C,D)
where A<B and C>D while A==C and B==D. I'm not sure I like
that.
What's the real use case where this matters? (Either the
speed of == comparisons or the ability to ==-compare dicts
containing complex numbers.)
----------------------------------------------------------------------
You can respond by visiting:
http://sourceforge.net/tracker/?func=detail&atid=305470&aid=421922&group_id=5470