Is everything greater than None?

15,573

Solution 1

None is always less than any datatype in Python 2 (see object.c).

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).

Solution 2

From the Python 2.7.5 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.

Share:
15,573
Attila O.
Author by

Attila O.

SRE @ Google.

Updated on July 13, 2022

Comments

  • Attila O.
    Attila O. almost 2 years

    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?

  • Tyler
    Tyler over 14 years
    This is for Python 2.x I assume?
  • Attila O.
    Attila O. over 14 years
    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...
  • Glenn Maynard
    Glenn Maynard over 14 years
    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.
  • John Feminella
    John Feminella over 14 years
    "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.
  • Rolf Bartstra
    Rolf Bartstra over 11 years
    Indeed it was extremely handy (e.g. input sanity checks) to allow comparisons between incomparable types, and to me it would seem logical to have such comparisons always return False - like when comparing numericals to NaN's. Unfortunately, this was not the case (e.g., None<0 returning True), and apparently in Python 3 this is handled by forbidding such comparisons altogether - a huge 'improvement' indeed ...! ;-)
  • HorseloverFat
    HorseloverFat over 11 years
    Having None compare less than everything feels much less arbitrary than having it compare greater than everything. Empty strings come before any other string, 'zero' comes before any positive integer, so intuitively, the None type comes before any other type.
  • endolith
    endolith about 11 years
    @GlennMaynard: Yes, ordering None in a list of numbers is arbitrary, because it's not a number. Currently, if parameter < 0 doesn't work if parameter=None by default, which is stupid. You can always do key=lambda x: float('-inf') if x is None else x or key=lambda x: float('inf') if x is None else x or key=lambda x: 0 if x is None else x, depending on which arbitrary ordering you prefer.
  • Karl Knechtel
    Karl Knechtel about 2 years
    @endolith I would argue that e.g. lambda x: (x is not None, x) is cleaner than special-casing None as float('-inf').