Is everything greater than None?
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 aTypeError
exception when the operands don’t have a meaningful natural ordering. Thus, expressions like:1 < ''
,0 > None
orlen <= len
are no longer valid, and e.g.None < None
raisesTypeError
instead of returningFalse
. 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.
Comments
-
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 over 14 yearsThis is for Python 2.x I assume?
-
Attila O. over 14 yearsThanks 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 over 14 yearsOf 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 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 over 11 yearsIndeed 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
returningTrue
), and apparently in Python 3 this is handled by forbidding such comparisons altogether - a huge 'improvement' indeed ...! ;-) -
HorseloverFat over 11 yearsHaving 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 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 ifparameter=None
by default, which is stupid. You can always dokey=lambda x: float('-inf') if x is None else x
orkey=lambda x: float('inf') if x is None else x
orkey=lambda x: 0 if x is None else x
, depending on which arbitrary ordering you prefer. -
Karl Knechtel about 2 years@endolith I would argue that e.g.
lambda x: (x is not None, x)
is cleaner than special-casingNone
asfloat('-inf')
.