-4

This is another huge trap I've met today.

I spend hours on debugging my code and finally I found it caused by this weird setting

Below is my python prompt interface

'3' > '2'
True
'4' > '3'
True
'15' > '11'
True
'999233' > '123'
True

# At this point, you must think compare string numbers is just like compare numbers.     
# Me too, but...

'5' > '15'
True

# What's this !!!???
# Meanwhile I am asking this question. I want to something exaggerated to mockerying 
# this mechanism, and I find something surprised me:

'5' > '999233'
False

# What!!!???
# Suddenly an idea come across my mind, are they comparing the first string number
# at first, if they are equal and then compare the second one?
# So I tried:

'5' > '13333333333333333'
True
'5' > '61'
False

# That's it.
# my old doubt disappeared and a new question raised:

Why they designed such a mechanism instead of use natural number comparison mechanism? What's the benefit to use this mechanism in "string number" comparison?

Chris Seymour
  • 83,387
  • 30
  • 160
  • 202
Mario
  • 921
  • 2
  • 10
  • 22
  • 1
    Google for lexicographic comparison – thefourtheye Mar 16 '14 at 11:19
  • 3
    What do you think the `'` around those digits means? – T.J. Crowder Mar 16 '14 at 11:21
  • 5
    I don't think this should be surprising. It would be surprising if string comparison worked in different ways depending on the content of the strings being compared. Strings are strings; it doesn't matter that in this case they happen to consist of a sequence of digits that can be interpreted as a decimal number. – Ismail Badawi Mar 16 '14 at 11:24
  • @T.J.Crowder , That forced them to be strings. The test I've made on them makes me believe their order is like normal numbers at first. – Mario Mar 16 '14 at 11:26
  • @Mario: Right, they're strings, not numbers, and that's how they're being compared. `'5' > '3'` for the same reason that `'e' > 'a'`. `'5' > '15'` for the same reason that `'e' > 'ae'`. – T.J. Crowder Mar 16 '14 at 12:13

6 Answers6

7

You are comparing Strings not numbers.

20 > 9 evaluates True for numeric types like integers and floats but with lexicographical comparison (strings) then '20' < '9' evaluates to True

Example:

$ python
>>> 5 > 10
False
>>> '5' > '10'
True
>>> '05' > '10'
False
>>> 'abc05' > 'bca10'
False
>>> 'dog' > 'cat'
True
>>> type('10')
<type 'str'>
>>> type(10)
<type 'int'>
Chris Seymour
  • 83,387
  • 30
  • 160
  • 202
Raul Guiu
  • 2,374
  • 22
  • 37
3

It is a lexicographical comparison. As soon as an element greater than the other is found the comparison stops, so

'5' > '15'

is true because '5' is greater than '1'

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Nikos Athanasiou
  • 29,616
  • 15
  • 87
  • 153
3

Indeed the ascii value of the character '5' is greater than the value '1' so '5' > '15' evaluates to True. As string comparison is byte by byte, just like the length of a word in the dictionary doesn't effect it's position '5' > '1412423513515' is also True.

>>> '5' > '15'
True
>>> ord('5')
53
>>> ord('1')
49

Think of the string representation of the integers like alphabetical characters i.e 'z' > 'abc' evaluates to True because 'z' comes after 'a'. This is called lexicographic ordering.

Chris Seymour
  • 83,387
  • 30
  • 160
  • 202
1

The answer is that strings are compared from the leftmost character, or "lexicographical ordering". This gives intuitive results for, for example,

"an" < "b" # True

If you want to compare the values of the numbers the strings represent, you should be explicit about that:

int("15") < int("5") # False
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
0

You are comparing strings since your numbers are surrounded by single quotes.

In python < and > operators applied on strings compare them using lexicographic order. You can test this putting a '0' before '5':

'05' > '11'
0

It's comparing the initial digit. Just as if it was alphabetical. 5 > 1 that's why you're getting 5 > 16

Mike Rapadas
  • 4,613
  • 2
  • 28
  • 21