Comparing None with built-in types using arithmetic operators?
Question:
Python 2.7.2 (default, Jun 12 2011, 14:24:46) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> None > 0
False
>>> None == 0
False
>>> None < 0
True
- Is comparing
None
using arithmetic operators well defined for built-in types (integers in this case)?
- Is the difference between the first two and the third comparison part of language specification (Python’s specification – you must be kidding :)) or is it CPython’s implementation detail?
Answers:
The only meaningful comparison you can really use with None
is if obj is None:
(or if obj is not None:
).
Comparison between different types has been removed from Python 3 for good reasons – they were a common source of errors and lead to confusion. For example
>>> "3" < 4
False
In Python 3, you get a TypeError
when comparing values of different types like str
vs. int
or anything vs. None
.
>>> None < 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: NoneType() < int()
(I mean “comparing” in the sense of trying to determine which of two values is larger/smaller. Comparison for equality is OK – it will always return False
if two object are of different types.)
I haven’t found a reference in the docs for this, but in Learning Python, 4th edition, Mark Lutz writes on page 204:
[…] Comparisons of differently typed objects (e.g., a string and a
list) work — the language defines a fixed ordering among different
types, which is deterministic, if not aesthetically pleasing. That is,
the ordering is based on the names of the types involved: all integers
are less than all strings, for example, because "int"
is less than
"str"
.
Some interesting quotes from http://bytes.com/topic/python/answers/801701-why-none-0-a
In early Python, the decision was made that the comparison of any
two objects was legal and would return a consistent result. So objects
of different types will compare according to an ordering on their
types (an implementation dependent, unspecified, but consistent
ordering), and objects of the same type will be compared according to
rules that make sense for that type.
Other implementations have the right to compare an integer and None
differently, but on a specific implementation, the result will not
change.
Python 3 will raise an exception on such comparisons.
and
The problem is the typical one; Python did not originally have a
Boolean type, and the retrofit resulted in weird semantics. C has the
same issue.
Python 2.7.2 (default, Jun 12 2011, 14:24:46) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> None > 0
False
>>> None == 0
False
>>> None < 0
True
- Is comparing
None
using arithmetic operators well defined for built-in types (integers in this case)? - Is the difference between the first two and the third comparison part of language specification (Python’s specification – you must be kidding :)) or is it CPython’s implementation detail?
The only meaningful comparison you can really use with None
is if obj is None:
(or if obj is not None:
).
Comparison between different types has been removed from Python 3 for good reasons – they were a common source of errors and lead to confusion. For example
>>> "3" < 4
False
In Python 3, you get a TypeError
when comparing values of different types like str
vs. int
or anything vs. None
.
>>> None < 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: NoneType() < int()
(I mean “comparing” in the sense of trying to determine which of two values is larger/smaller. Comparison for equality is OK – it will always return False
if two object are of different types.)
I haven’t found a reference in the docs for this, but in Learning Python, 4th edition, Mark Lutz writes on page 204:
[…] Comparisons of differently typed objects (e.g., a string and a
list) work — the language defines a fixed ordering among different
types, which is deterministic, if not aesthetically pleasing. That is,
the ordering is based on the names of the types involved: all integers
are less than all strings, for example, because"int"
is less than
"str"
.
Some interesting quotes from http://bytes.com/topic/python/answers/801701-why-none-0-a
In early Python, the decision was made that the comparison of any
two objects was legal and would return a consistent result. So objects
of different types will compare according to an ordering on their
types (an implementation dependent, unspecified, but consistent
ordering), and objects of the same type will be compared according to
rules that make sense for that type.Other implementations have the right to compare an integer and None
differently, but on a specific implementation, the result will not
change.Python 3 will raise an exception on such comparisons.
and
The problem is the typical one; Python did not originally have a
Boolean type, and the retrofit resulted in weird semantics. C has the
same issue.