In python 3, int(50)<\'2\'
causes a TypeError
, and well it should. In python 2.x, however, int(50)<\'2\'
returns True
It works like this1.
>>> float() == long() == int() < dict() < list() < str() < tuple()
True
Numbers compare as less than containers. Numeric types are converted to a common type and compared based on their numeric value. Containers are compared by the alphabetic value of their names.2
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.
Objects of different builtin types compare alphabetically by the name of their type .int
starts with an 'i' and str
starts with an s
so any int
is less than any str
.
In response to the comment about long < int
>>> int < long
True
You probably meant values of those types though, in which case the numeric comparison applies.
1 This is all on Python 2.6.5
2 Thank to kRON for clearing this up for me. I'd never thought to compare a number to a dict
before and comparison of numbers is one of those things that's so obvious that it's easy to overlook.
The reason why these comparisons are allowed, is sorting. Python 2.x can sort lists containing mixed types, including strings and integers -- integers always appear first. Python 3.x does not allow this, for the exact reasons you pointed out.
Python 2.x:
>>> sorted([1, '1'])
[1, '1']
>>> sorted([1, '1', 2, '2'])
[1, 2, '1', '2']
Python 3.x:
>>> sorted([1, '1'])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: str() < int()
(And who thought it was a good idea to allow this to begin with???)
I can imagine that the reason might be to allow object from different types to be stored in tree-like structures, which use comparisons internally.
As Aaron said. Breaking it up into your points:
So, it doesn't make sense in the general case, but occasionally it's helpful.
from random import shuffle
letters=list('abcdefgh')
ints=range(8)
both=ints+letters
shuffle(ints)
shuffle(letters)
shuffle(both)
print sorted(ints+letters)
print sorted(both)
Both print the ints first, then the letters.
As a rule, you don't want to mix types randomly within a program, and apparently Python 3 prevents it where Python 2 tries to make vague sense where none exists. You could still sort by lambda a,b: cmp(repr(a),repr(b))
(or something better) if you really want to, but it appears the language developers agreed it's impractical default behaviour. I expect it varies which gives the least surprise, but it's a lot harder to detect a problem in the Python 2 sense.