How does Python 2 compare string and int? Why do lists compare as greater than numbers, and tuples greater than lists?
From the python 2 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.
When you order two strings or two numeric types the ordering is done in the expected way (lexicographic ordering for string, numeric ordering for integers).
When you order a numeric and a non-numeric type, the numeric type comes first.
>>> 5 < 'foo'
True
>>> 5 < (1, 2)
True
>>> 5 < {}
True
>>> 5 < [1, 2]
True
When you order two incompatible types where neither is numeric, they are ordered by the alphabetical order of their typenames:
>>> [1, 2] > 'foo' # 'list' < 'str'
False
>>> (1, 2) > 'foo' # 'tuple' > 'str'
True
>>> class Foo(object): pass
>>> class Bar(object): pass
>>> Bar() < Foo()
True
One exception is old-style classes that always come before new-style classes.
>>> class Foo: pass # old-style
>>> class Bar(object): pass # new-style
>>> Bar() < Foo()
False
Is this behavior mandated by the language spec, or is it up to implementors?
There is no language specification. The language reference says:
Otherwise, objects of different types always compare unequal, and are ordered consistently but arbitrarily.
So it is an implementation detail.
Are there differences between any of the major Python implementations?
I can't answer this one because I have only used the official CPython implementation, but there are other implementations of Python such as PyPy.
Are there differences between versions of the Python language?
In Python 3.x the behaviour has been changed so that attempting to order an integer and a string will raise an error:
>>> '10' > 5
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
'10' > 5
TypeError: unorderable types: str() > int()
Python2 comparing tuple and int?
The difference in behavior is described in the docs:
https://docs.python.org/2/library/stdtypes.html#comparisons
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). Furthermore, some types (for example, file objects) support only a degenerate notion of comparison where any two objects of that type are unequal. Again, such objects are ordered arbitrarily but consistently. The <, <=, > and >= operators will raise a TypeError exception when any operand is a complex number.
As you already noticed, comparing tuples and integers no longer work in Python 3, due to some changes in the comparison mechanics:
https://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons
- The ordering comparison operators (<, <=, >=, >) raise a TypeError exception when the operands don’t have a meaningful natural ordering. Thus, expressions like 1 < '', 0 > None or len <= len are no longer valid, and e.g. None < None raises TypeError instead of returning False. A corollary is that sorting a heterogeneous list no longer makes sense – all the elements must be comparable to each other. Note that this does not apply to the == and != operators: objects of different incomparable types always compare unequal to each other.
- builtin.sorted() and list.sort() no longer accept the cmp argument providing a comparison function. Use the key argument instead. N.B. the key and reverse arguments are now “keyword-only”.
- The cmp() function should be treated as gone, and the cmp() special method is no longer supported. Use lt() for sorting, eq() with hash(), and other rich comparisons as needed. (If you really need the cmp() functionality, you could use the expression (a > b) - (a < b) as the equivalent for cmp(a, b).)
How does tuple comparison work in Python?
Tuples are compared position by position:
the first item of the first tuple is compared to the first item of the second tuple; if they are not equal (i.e. the first is greater or smaller than the second) then that's the result of the comparison, else the second item is considered, then the third and so on.
See Common Sequence Operations:
Sequences of the same type also support comparisons. In particular, tuples and lists are compared lexicographically by comparing corresponding elements. This means that to compare equal, every element must compare equal and the two sequences must be of the same type and have the same length.
Also Value Comparisons for further details:
Lexicographical comparison between built-in collections works as follows:
- For two collections to compare equal, they must be of the same type, have the same length, and each pair of corresponding elements must compare equal (for example,
[1,2] == (1,2)
is false because the type is not the same).- Collections that support order comparison are ordered the same as their first unequal elements (for example,
[1,2,x] <= [1,2,y]
has the same value asx <= y
). If a corresponding element does not exist, the shorter collection is ordered first (for example,[1,2] < [1,2,3]
is true).
If not equal, the sequences are ordered the same as their first differing elements. For example, cmp([1,2,x], [1,2,y]) returns the same as cmp(x,y). If the corresponding element does not exist, the shorter sequence is considered smaller (for example, [1,2] < [1,2,3] returns True).
Note 1: <
and >
do not mean "smaller than" and "greater than" but "is before" and "is after": so (0, 1) "is before" (1, 0).
Note 2: tuples must not be considered as vectors in a n-dimensional space, compared according to their length.
Note 3: referring to question https://stackoverflow.com/questions/36911617/python-2-tuple-comparison: do not think that a tuple is "greater" than another only if any element of the first is greater than the corresponding one in the second.
comparing a list against an int in Python
One could think Python 2 compares names alphabetically:
print(list>int) # True
print(set>list) # True
print(float<int) # True
until you try
print(dict<list) # False
Then you need to read the documentation: comparisons
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). Furthermore, some types (for example, file objects) support only a degenerate notion of comparison where any two objects of that type are unequal.
Again, such objects are ordered arbitrarily but consistently. The
<
,<=
,>
and>=
operators will raise aTypeError
exception when any operand is a complex number.
(emphasis mine)
This allows your to do:
k = [ 1, "a", 'c', 2.4, {1:3}, "hallo", [1,2,3], [], 4.92, {}] # wild mix of types
k.sort() # [1, 2.4, 4.92, {}, {1: 3}, [], [1, 2, 3], 'a', 'c', 'hallo'] type-sorted
In python 3 you get
TypeError: '>' not supported between instances of ... and ...
- http://pythonclock.org
How to compare string and integer in python?
Convert the string to an integer with int
:
hours = int("14")
if (hours > 14):
print "yes"
In CPython2, when comparing two non-numerical objects of different types, the comparison is performed by comparing the names of the types. Since 'int' < 'string'
, any int is less than any string.
In [79]: "14" > 14
Out[79]: True
In [80]: 14 > 14
Out[80]: False
This is a classic Python pitfall. In Python3 this wart has been corrected -- comparing non-numerical objects of different type raises a TypeError by default.
As explained in 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.
Related Topics
How to Use "/" (Directory Separator) in Both Linux and Windows in Python
Cross-Platform Subprocess With Hidden Window
Yes' Reporting Error With Subprocess Communicate()
Use the Default Python Rather Than the Anaconda Installation When Called from the Terminal
Os.Walk Without Hidden Folders
Python Script as Linux Service/Daemon
Compare Two Images the Python/Linux Way
Packaging a Python Script on Linux into a Windows Executable
Ensure a Single Instance of an Application in Linux
How to Kill a Python Child Process Created With Subprocess.Check_Output() When the Parent Dies
Standard_Init_Linux.Go:178: Exec User Process Caused "Exec Format Error"
Call Python Script from Bash With Argument
How to Get Monotonic Time Durations in Python
Simulate Keystroke in Linux With Python
How to Make Python Script Run as Service
How to Listen For 'Usb Device Inserted' Events in Linux, in Python