Annoying behaviour of the != operator
Dan Sommers
me at privacy.net
Fri Jun 10 13:51:24 EDT 2005
On Fri, 10 Jun 2005 09:50:56 -0500,
Rocco Moretti <roccomoretti at hotpop.com> wrote:
> Dan Sommers wrote:
>> On Thu, 09 Jun 2005 15:50:42 +1200,
>> Greg Ewing <greg at cosc.canterbury.ac.nz> wrote:
>>
>>> Rocco Moretti wrote:
>>>
>>>> The main problem is that Python is trying to stick at least three
>>>> different concepts onto the same set of operators: equivalence (are
>>>> these two objects the same?), ordering (in a sorted list, which comes
>>>> first?), and mathematical "size".
>>
>>>> This gives the wacky world where
>>>> "[(1,2), (3,4)].sort()" works, whereas "[1+2j, 3+4j].sort()" doesn't.
>> Python inherits that wackiness directly from (often wacky) world of
>> Mathematics.
>> IMO, the true wackiness is that
>> [ AssertionError, (vars, unicode), __name__, apply ].sort( )
>> "works," too. Python refusing to sort my list of complex numbers is a
>> Good Thing.
> The "wackyness" I refered to wasn't that a list of complex numbers isn't
> sortable, but the inconsistent behaviour of list sorting. As you
> mentioned, an arbitraty collection of objects in a list is sortable, but
> as soon as you throw a complex number in there, you get an exception.
Yes, I agree: it is inconsistent.
> One way to handle that is to refuse to sort anything that doesn't have
> a "natural" order. But as I understand it, Guido decided that being
> able to sort arbitrary lists is a feature, not a bug. But you can't
> sort ones with complex numbers in them, because you also want
> '1+3j<3+1j' to raise an error.
As George Sakkis noted, Guido has since recanted. Unfortunately, in
this case, the time machine would have broken too much existing code.
>> Four separate classes of __comparison__ methods in a language that
>> doesn't (and can't and shouldn't) preclude or warn about rules
>> regarding which methods "conflict" with which other methods? I do
>> not claim to be an expert, but that doesn't seem very Pythonic to me.
> What "conflict"? Where are you getting the doesn't/can't/shouldn't
> prescription from?
Perhaps "conflict" wasn't quite the right word. For example, if I
define __ne__ and __equal__ and __lt__, then which method(s) should
Python use if I later use a <= or a >= operator?
"Doesn't" and "can't" (call me pessimistic) comes from all the issues
and disagreements we're having in this thread, and "shouldn't" comes
from the Zen:
Explicit is better than implicit.
In the face of ambiguity, refuse the temptation to guess.
> Which method you use depends on what you want to achieve:
> (Hypothetical Scheme)
> Object Identity? - use 'is'
> Mathematical Ordering? - use '__eq__' & friends
> Object Equivalence? - use '__equiv__'
> Arbitrary Ordering? (e.g. for list sorting) - use '__order__'
So which method would python use when sorting a list that happens to
consist only of numbers? or a list that contains mostly integers and a
few complex numbers?
> The only caveat is to define sensible defaults for the cases where one
> fuction is not defined. But that shouldn't be too hard.
At the risk of repeating myself:
Explicit is better than implicit.
In the face of ambiguity, refuse the temptation to guess.
Also, as I noted in a previous discussion on an unrelated topic, it
seems that we all have our own notions and limitations of expliciticity
and impliciticity.
> __eqiv__ -> __eq__ -> is
> __order__ -> __lt__/__cmp__
>> AIUI, __cmp__ exists for backwards compatibility, and __eq__ and friends
>> are flexible enough to cover any possible comparison scheme.
> Except if you want the situation where "[1+2j, 3+4j].sort()" works, and
> '1+3j < 3+1j' fails.
I'm sticking with my position that both should fail, unless you
*explicity* tell sort what to do (since for now, we all seem to agree
that the other one should fail). If I have an application that thinks
it has to sort a list of arbitrary objects, then I have to be clever
enough to help.
> I think the issue is you thinking along the lines of Mathematical
> numbers, where the four different comparisons colapse to one. Object
> identity? There is only one 'two' - heck, in pure mathematics, there
> isn't even a 'float two'/'int two' difference. Equivalence *is*
> mathematical equality, and the "arbitrary ordering" is easily defined
> as "true" ordering. It's only when you break away from mathematics do
> you see the divergance in behavior.
IIRC, there was a discussion about overhauling of all of Python's
numbers to make them act more like the mathematical entities that they
represent rather than the Python objects that they are. The long/int
"consolidation," better handling of integer division, and the Decimal
class came out of that discussion. But that still leaves the issue of
what to do with 1 < "foo" and "bar" > 2j and 3j < 4j.
Regards,
Dan
--
Dan Sommers
<http://www.tombstonezero.net/dan/>
More information about the Python-list
mailing list