9

I recently discovered a typo in my program

while len(first_list) > second_list:
    do_stuff

I played around with this and discovered that 5 < ["apple"] == True and 5 > ["apple"] == False

Why does Python allow these sorts of comparisons? What is being evaluated under the hood to determine that 5 is less than ["apple"]?

Trajanson
  • 441
  • 3
  • 11
  • 9
    Because Python 2 is broken by design, you should use Python 3 which will raise an exception if you try such comparison. – Delgan Dec 03 '16 at 08:43

3 Answers3

4

I think that the types are compared in this case, so it's like writing:

type(5) < type(["apple"])

and since "int" and "list" are compared lexicographically ("i" < "l"), you're getting this output.

If you try:

"5" > ["apple"]

you'll get False, since "string" > "list".

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.

Maroun
  • 94,125
  • 30
  • 188
  • 241
  • Any document or source code link demonstrating this will be helpful. Without that it is just a assumption – Moinuddin Quadri Dec 03 '16 at 08:51
  • See this other question on SO: [How does Python compare string and int?](http://stackoverflow.com/a/3270689/2291710) – Delgan Dec 03 '16 at 08:52
  • 2
    Not correct. `{}<0` evaluates to False, but `dictionary` comes before `int` – yelsayed Dec 03 '16 at 08:52
  • @yBot I added the link that I think justifies my assumption. – Maroun Dec 03 '16 at 09:00
  • I don't see how this justifies your assumption. The quote only says objects of the same type are ordered by their addresses, says nothing about ordering different types using the type name lexicographically. – yelsayed Dec 03 '16 at 09:02
  • @yBot Related: http://stackoverflow.com/questions/3270680/how-does-python-compare-string-and-int – Maroun Dec 03 '16 at 09:04
  • 3
    @yBot "Objects of different types **except** numbers [...]" – Jasper Dec 03 '16 at 09:04
  • I still don't see how that explains it. That post is totally wrong as far as I can see, there's nothing in the official docs about this, only a CPython implementation detail. – yelsayed Dec 03 '16 at 09:36
  • 1
    This post is totally right except for the example with the number 5. – Jasper Dec 03 '16 at 09:41
3

Its from documentation of python 2:

The operators <, >, ==, >=, <=, and != compare the values of two objects. The objects need not have the same type. If both are numbers, they are converted to a common type. Otherwise, objects of different types always compare unequal, and are ordered consistently but arbitrarily. You can control comparison behavior of objects of non-builtin types by defining a __cmp__ method or rich comparison methods like __gt__.

salmanwahed
  • 9,450
  • 7
  • 32
  • 55
-3

According to this, different types just have to compare unequal, it's up to the implementation to decide how to handle that. It just so happens that CPython's implementation decides to order based on type names.

yelsayed
  • 5,236
  • 3
  • 27
  • 38
  • Any specific reason for the down votes? – yelsayed Dec 03 '16 at 09:36
  • downvotes are probably because this answer doesn't really answer anything but just guesses... and actually, it's _not_ up to the implementation. – mb21 Dec 03 '16 at 09:56
  • Care to explain? Where in the official docs does it define this? – yelsayed Dec 03 '16 at 10:00
  • 2
    see the other answers? – mb21 Dec 03 '16 at 10:01
  • 1
    I did. Other answers along with their examples are all about CPython, nothing about the official language docs – yelsayed Dec 03 '16 at 10:01
  • ah, sorry... you're right. it's implementation dependent. but it must be deterministic. either way, your answer isn't all that helpful compared to e.g. http://stackoverflow.com/a/3270689/214446 (btw, I didn't downvote) – mb21 Dec 03 '16 at 10:04
  • Ah well, it was still a useful discussion that shouldn't get down voted. So much for wisdom of the masses I guess. Sigh. – yelsayed Dec 03 '16 at 10:07
  • I think you should link to Python 2 documentation when answering Python 2-specific question. It will at least explain the behavior of the code from the question. – vaultah Dec 03 '16 at 10:19
  • Thanks for the catch. Fixed the answer for what it's worth. – yelsayed Dec 03 '16 at 10:33