32

In Python, None evaluates to less than zero?

ActivePython 2.7.2.5 (ActiveState Software Inc.) based on
Python 2.7.2 (default, Jun 24 2011, 12:21:10) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> None < 0
True
>>> None == 0
False
>>> None > 0
False
>>>

Is this expected?

I would have guessed that None would either be equal to zero (through type coercion), or that all of these statements would return False.

moooeeeep
  • 31,622
  • 22
  • 98
  • 187
Mike M. Lin
  • 9,992
  • 12
  • 53
  • 62
  • 14
    For what it's worth, you can't do that any more in Python 3. It will give you this error: `TypeError: unorderable types: NoneType() < int()` – NullUserException Sep 12 '11 at 06:12
  • @NullUserException: that's good to know. Because this is not the kind of intuitive behaviour that I expect from Python. – Joachim Sauer Sep 12 '11 at 06:14
  • 3
    Don't forget, even though it is dynamically typed, Python is still **strongly** typed: that is, no implicit coercions are performed. – Daniel Roseman Sep 12 '11 at 08:16
  • 1
    @Daniel They are if you compare a `bool` to an `int` (or at least so it seems) – NullUserException Sep 12 '11 at 13:16
  • 2
    To expand on @NullUserException, the bools are actually explicitly stated to be very thin wrappers around the integer constants `0` and `1` with special `__str__` and `__repr__`. Math, logic and everything else works exactly the same on both, `bool` is even a subclass of `int`. That's as much of an implicit conversion as `1 + 1.0` resulting in a float. –  Sep 12 '11 at 14:12

3 Answers3

15

See the manual:

Objects of different types, except different numeric types and different string types, never compare equal; such objects are ordered consistently but arbitrarily (so that sorting a heterogeneous array yields a consistent result).

and

CPython implementation detail: Objects of different types except numbers are ordered by their type names; objects of the same types that don’t support proper comparison are ordered by their address.

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
5

From the docs:

CPython implementation detail: Objects of different types except numbers are ordered by their type names; objects of the same types that don’t support proper comparison are ordered by their address.

NoneType compares as smaller than int since the comparison appears to be case-sensitive.

>>> type(0)
<type 'int'>
>>> type(None)
<type 'NoneType'>
>>> 'NoneType' < 'int'
True
hammar
  • 138,522
  • 17
  • 304
  • 385
  • 3
    This can't be right, since `print(5 > {})` gives you false, and `int > dict` – NullUserException Sep 12 '11 at 06:16
  • @NullUserException: Interesting. That would seem to contradict the documentation, unless I'm missing something. – hammar Sep 12 '11 at 06:22
  • @NullUserException: `type(5) > type({})` gives false, so that part is consistent, though I'm not sure why they compare that way when, as you said, `int > dict`. However, `type(None) > type(0)`. Hmm.... – hammar Sep 12 '11 at 06:31
  • @NullUserException @hammar - I get `int < dict` here, on Python 2.6.6. But also the inconsistent `type(None) > type(0)` but `None < 0`... – detly Sep 12 '11 at 06:52
  • @NullUserException: The doc says "Objects of different types **except numbers**" (emphasis mine). – Marco Leogrande Jul 28 '14 at 23:58
  • you're just comparing two strings >>> 'N' < 'i' True – JoulinRouge Apr 17 '20 at 14:08
3

It is intentional to make operations like sorting and dictionary comparison well defined.

[citing from the Language Reference]

The operators <, >, ==, >=, <=, and != compare the values of two objects. The objects need not have the same type. If both are numbers, they are converted to a common type. Otherwise, objects of different types always compare unequal, and are ordered consistently but arbitrary.

Maxim Razin
  • 9,114
  • 7
  • 34
  • 33