Why does the following piece behave like it behaves?
>>> '10' > 100
True
>>> 100 < '10'
True
Shouldn't it raise an exception?
Why does the following piece behave like it behaves?
>>> '10' > 100
True
>>> 100 < '10'
True
Shouldn't it raise an exception?
From the documentation:
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.
So it's just something that happens in CPython ('int' < 'str'
), but that isn't guaranteed to happen in other implementations.
In fact, this behaviour has been removed in python3:
>>> '10' > 100
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: str() > int()
>>> 100 < '10'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < str()
From manual:
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.
So if you compare this two types: int / string
you have a lexicographic order bye the type of elements
Because Python implements implicit type conversions for numbers so they may be printed as strings without doing an explicit conversion.
Python is converting 1000
into the string "1000"
when doing the comparison to the string "10"
. And according to the Python intepreter, "1000"
is indeed larger than "10".
This is why: "I've got %s bananas" % 5000
works, and unlike in C or another language without implicit type conversion, I didn't have to do printf("I've got %i bananas", 5000);
Check out Python docs chapter 5: Built-in Types
different operators are getting called, at one point int's __gt__
, at another, str's __lt__
check this:
class t(int):
def __gt__(self, other):
print 'here', v
return v
class t2(str):
def __lt__(self, other):
v = super(t2, self).__lt__(other)
print 'ohere', v
return v
if __name__ == '__main__':
a = t('10')
b = t2(100)
a > b
b < a
I am not 100% sure, but some internal type conversion might be happening here. It might be doing what is called lexicographic comparison, where '1' which is 49 in ASCII is greater than 1 (the first digit), and so on.