What does x[x < 2] = 0 mean in Python?

前端 未结 5 745
南方客
南方客 2020-12-24 04:42

I came across some code with a line similar to

x[x<2]=0

Playing around with variations, I am still stuck on what this syntax does.

5条回答
  •  一生所求
    2020-12-24 04:59

    The original code in your question works only in Python 2. If x is a list in Python 2, the comparison x < y is False if y is an integer. This is because it does not make sense to compare a list with an integer. However in Python 2, if the operands are not comparable, the comparison is based in CPython on the alphabetical ordering of the names of the types; additionally all numbers come first in mixed-type comparisons. This is not even spelled out in the documentation of CPython 2, and different Python 2 implementations could give different results. That is [1, 2, 3, 4, 5] < 2 evaluates to False because 2 is a number and thus "smaller" than a list in CPython. This mixed comparison was eventually deemed to be too obscure a feature, and was removed in Python 3.0.


    Now, the result of < is a bool; and bool is a subclass of int:

    >>> isinstance(False, int)
    True
    >>> isinstance(True, int)
    True
    >>> False == 0
    True
    >>> True == 1
    True
    >>> False + 5
    5
    >>> True + 5
    6
    

    So basically you're taking the element 0 or 1 depending on whether the comparison is true or false.


    If you try the code above in Python 3, you will get TypeError: unorderable types: list() < int() due to a change in Python 3.0:

    Ordering Comparisons

    Python 3.0 has simplified the rules for 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.


    There are many datatypes that overload the comparison operators to do something different (dataframes from pandas, numpy's arrays). If the code that you were using did something else, it was because x was not a list, but an instance of some other class with operator < overridden to return a value that is not a bool; and this value was then handled specially by x[] (aka __getitem__/__setitem__)

提交回复
热议问题