views:

179

answers:

2

Is there a Python built-in datatype, besides None, for which:

>>> not foo > None
True

where foo is a value of that type? How about Python 3?

+12  A: 

None is always less than any datatype in Python 2.

In Python 3, this was changed; now doing comparisons on things without a sensible natural ordering results in a TypeError. From the 3.0 "what's new" updates:

Python 3.0 has simplified the rules for ordering comparisons:

The ordering comparison operators (<, <=, >=, >) raise a TypeError exception when the operands don’t have a meaningful natural ordering. Thus, expressions like 1 < '', 0 > None or len <= len are no longer valid, and e.g. None < None raises TypeError instead of returning False. A corollary is that sorting a heterogeneous list no longer makes sense – all the elements must be comparable to each other. Note that this does not apply to the == and != operators: objects of different incomparable types always compare unequal to each other.

This upset some people since it was often handy to do things like sort a list that had some None values in it, and have the None values appear clustered together at the beginning or end. There was a thread on the mailing list about this a while back, but the ultimate point is that Python 3 tries to avoid making arbitrary decisions about ordering (which is what happened a lot in Python 2).

John Feminella
Thanks for clarifying the state of Python 3. I remember reading the "what's new" page but I don't remember this one. Very interesting, but it makes sense indeed...
Attila Oláh
Of course, there's nothing arbitrary about ordering None, as long as it's clearly defined. This sort of gratuitous incompatibility is why Python 3 adoption is taking so long.
Glenn Maynard
"Well-defined" (clear, explicit definition of behavior) is distinct from "arbitrary" (a choice made based on discretion). For example, one could just as easily have said "None compares greater than everything". That's equally well-defined, but still quite arbitrary.
John Feminella
+7  A: 

From the Python 2.6 source (object.c):

static int
default_3way_compare(PyObject *v, PyObject *w)
{
    ...
    /* None is smaller than anything */
    if (v == Py_None)
            return -1;
    if (w == Py_None)
            return 1;
    ...

}

EDIT: Added version number.

Torsten Marek
This is for Python 2.x I assume?
MatrixFrog
the link is 2.6
Corey Goldberg
Thanks, this is a very clear answer!
Attila Oláh