I'm wondering how Python does string comparison, more specifically how it determines the outcome when a less than (<
) or greater than (>
) operator is used.
For instance if I put print('abc' < 'bac')
I get True
. I understand that it compares corresponding characters in the string, however its unclear as to why there is more, for lack of a better term, "weight" placed on the fact that a is less than b (first position) in first string rather than the fact that a is less than b in the second string (second position).
From the docs:
Also:
or on Python 2:
As an example:
The result
False
is returned as soon asa
is found to be less thanb
. The further items are not compared (as you can see for the second items:b
>a
isTrue
).Be aware of lower and uppercase:
Python and just about every other computer language use the same principles as (I hope) you would use when finding a word in a printed dictionary:
(1) Depending on the human language involved, you have a notion of character ordering: 'a' < 'b' < 'c' etc
(2) First character has more weight than second character: 'az' < 'za' (whether the language is written left-to-right or right-to-left or boustrophedon is quite irrelevant)
(3) If you run out of characters to test, the shorter string is less than the longer string: 'foo' < 'food'
Typically, in a computer language the "notion of character ordering" is rather primitive: each character has a human-language-independent number
ord(character)
and characters are compared and sorted using that number. Often that ordering is not appropriate to the human language of the user, and then you need to get into "collating", a fun topic.Strings are compared lexicographically using the numeric equivalents (the result of the built-in function ord()) of their characters. Unicode and 8-bit strings are fully interoperable in this behavior.
This is a lexicographical ordering. It just puts things in dictionary order.
Take a look also at How do I sort unicode strings alphabetically in Python? where the discussion is about sorting rules given by the Unicode Collation Algorithm (http://www.unicode.org/reports/tr10/).
To reply to the comment
by S.Lott, there is a famous counter-example when sorting French language. It involves accents: indeed, one could say that, in French, letters are sorted left-to-right and accents right-to-left. Here is the counter-example: we have e < é and o < ô, so you would expect the words cote, coté, côte, côté to be sorted as cote < coté < côte < côté. Well, this is not what happens, in fact you have: cote < côte < coté < côté, i.e., if we remove "c" and "t", we get oe < ôe < oé < ôé, which is exactly right-to-left ordering.
And a last remark: you shouldn't be talking about left-to-right and right-to-left sorting but rather about forward and backward sorting.
Indeed there are languages written from right to left and if you think Arabic and Hebrew are sorted right-to-left you may be right from a graphical point of view, but you are wrong on the logical level!
Indeed, Unicode considers character strings encoded in logical order, and writing direction is a phenomenon occurring on the glyph level. In other words, even if in the word שלום the letter shin appears on the right of the lamed, logically it occurs before it. To sort this word one will first consider the shin, then the lamed, then the vav, then the mem, and this is forward ordering (although Hebrew is written right-to-left), while French accents are sorted backwards (although French is written left-to-right).
Python string comparison is lexicographic:
From Python Docs: http://docs.python.org/reference/expressions.html
Hence in your example,
'abc' < 'bac'
, 'a' comes before (less-than) 'b' numerically (in ASCII and Unicode representations), so the comparison ends right there.