43

In Python 2.x:

>>> '' > 0
True

Why is that?

wim
  • 338,267
  • 99
  • 616
  • 750
parxier
  • 3,811
  • 5
  • 42
  • 54
  • 23
    BTW, Python 3.0 produces a `TypeError: unorderable types: str() > int()` for the same comparison – mjv Mar 05 '10 at 02:01
  • Related http://stackoverflow.com/questions/18387938/how-do-python-comparison-operators-and-work-with-a-function-name-as-an-opera – Mazdak Jun 02 '15 at 07:24

2 Answers2

93

The original design motivation for allowing order-comparisons of arbitrary objects was to allow sorting of heterogeneous lists -- usefully, that would put all strings next to each other in alphabetical order, and all numbers next to each other in numerical order, although which of the two blocks came first was not guaranteed by the language. For example, this allowed getting only unique items in any list (even one with non-hashable items) in O(N log N) worst-case time

Over the years, this pragmatic arrangement eroded. The first crack came when the ability to order-compare complex numbers was taken away, quite a few versions ago. Suddenly, the ability to sort any list disappeared: it did not apply any more if the list contained complex numbers, possibly together with items of other types. Then Guido started disliking heterogeneous lists more generally, and thus started thinking that it didn't really matter if such lists could be usefully sorted or not... because such lists should not exist in the first place, according to his new thinking. He didn't do anything to forbid them, but was not inclined to accept any compromises to support them either.

Note that both changes move the balance a little bit away from the "practicality beats purity" item of the Zen of Python (which was written earlier, back when complex numbers still could be order-compared ;-) – a bit more purity, a bit less practicality.

Nevertheless the ability to order-compare two arbitrary objects (as long as neither was a complex number ;-) remained for a long time, because around that same time Guido started really insisting on maintaining strong backwards compatibility (a shift that's both practical and pure ;-).

So, it's only in Python 3, which explicitly and deliberately removed the constraint of strong backwards compatibility to allow some long-desired but backwards incompatible enhancements (especially simplifications and removal of obsolete, redundant way to perform certain tasks), that order comparison of instances of different types became an error.

So this historical and philosophical treatise is basically the only way to truly respond to your "why" question...! :-)

Praveen
  • 6,872
  • 3
  • 43
  • 62
Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • 1
    One should maybe add that while the language may not have this feature anymore, sorting of arbitrary lists can easily be down with a custom comparator. Just write it yourself in case you need it - would also be a very practical approach. – NoDataDumpNoContribution Jun 02 '15 at 08:07
  • 1
    Note : In Python 2, a complex number can be compared to any other object, except another complex number! `complex(1,0) > 'abc'` is `False` but `complex(1,0) > complex(0,0)` raises a `TypeError` – Eric Duminil Jan 22 '17 at 18:52
  • 2
    @EricDuminil Not exactly right - complex can not be compared to bools, ints, or fractions. For some reason (oversight, probably) they can be compared with decimals. – wim Oct 19 '20 at 18:49
  • @wim: Thanks for the interesting comment. You are technically correct : the best kind of correct! It would almost make sense since we can consider bools, ints, fractions and floats to belong to complex numbers. But decimals should be there, too. It's for python2 anyway, so it's becoming less relevant with time. – Eric Duminil Oct 19 '20 at 19:22
23

from https://docs.python.org/2.7/tutorial/datastructures.html#id1

Note that comparing objects of different types is legal. The outcome is deterministic but arbitrary: the types are ordered by their name. Thus, a list is always smaller than a string, a string is always smaller than a tuple, etc. [1] Mixed numeric types are compared according to their numeric value, so 0 equals 0.0, etc.

Pavel Shishpor
  • 742
  • 6
  • 14
Dyno Fu
  • 8,753
  • 4
  • 39
  • 64