Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is int(50)<str(5) in python 2.x?

In python 3, int(50)<'2' causes a TypeError, and well it should. In python 2.x, however, int(50)<'2' returns True (this is also the case for other number formats, but int exists in both py2 and py3). My question, then, has several parts:

  1. Why does Python 2.x (< 3?) allow this behavior?
  • (And who thought it was a good idea to allow this to begin with???)
  • What does it mean that an int is less than a str?
    • Is it referring to ord / chr?
    • Is there some binary format which is less obvious?
  • Is there a difference between '5' and u'5' in this regard?
  • like image 507
    cwallenpoole Avatar asked Nov 24 '10 12:11

    cwallenpoole


    2 Answers

    It works like this1.

    >>> float() == long() == int() < dict() < list() < str() < tuple()
    True
    

    Numbers compare as less than containers. Numeric types are converted to a common type and compared based on their numeric value. Containers are compared by the alphabetic value of their names.2

    From 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.

    Objects of different builtin types compare alphabetically by the name of their type int starts with an 'i' and str starts with an s so any int is less than any str..

    1. I have no idea.
      • A drunken master.
    2. It means that a formal order has been introduced on the builtin types.
      • It's referring to an arbitrary order.
      • No.
    3. No. strings and unicode objects are considered the same for this purpose. Try it out.

    In response to the comment about long < int

    >>> int < long
    True
    

    You probably meant values of those types though, in which case the numeric comparison applies.

    1 This is all on Python 2.6.5

    2 Thank to kRON for clearing this up for me. I'd never thought to compare a number to a dict before and comparison of numbers is one of those things that's so obvious that it's easy to overlook.

    like image 79
    aaronasterling Avatar answered Nov 12 '22 23:11

    aaronasterling


    The reason why these comparisons are allowed, is sorting. Python 2.x can sort lists containing mixed types, including strings and integers -- integers always appear first. Python 3.x does not allow this, for the exact reasons you pointed out.

    Python 2.x:

    >>> sorted([1, '1'])
    [1, '1']
    >>> sorted([1, '1', 2, '2'])
    [1, 2, '1', '2']
    

    Python 3.x:

    >>> sorted([1, '1'])
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unorderable types: str() < int()
    
    like image 6
    intgr Avatar answered Nov 12 '22 22:11

    intgr