Is everything greater than None?
Asked Answered
M

2

77

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?

Malva answered 6/2, 2010 at 18:32 Comment(2)
See also (not a duplicate): stackoverflow.com/questions/3270680Niple
I like the metaphysical tone of the question title.Gribble
I
98

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

Infancy answered 6/2, 2010 at 18:38 Comment(7)
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...Malva
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.Lezlie
"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.Infancy
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 ...! ;-)Christinchristina
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.Dolf
@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.Garges
@Garges I would argue that e.g. lambda x: (x is not None, x) is cleaner than special-casing None as float('-inf').Niple
E
30

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.

Explanation answered 6/2, 2010 at 18:40 Comment(1)
This is for Python 2.x I assume?Potamic

© 2022 - 2024 — McMap. All rights reserved.