Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is `0 is 0` always `True` in Python?

Python 3.8 (or CPython 3.8?) added the warning

SyntaxWarning: "is" with a literal. Did you mean "=="?

for the code 0 is 0.

I understand the warning, and I know the difference between is and ==.

However, I also know that CPython caches the object for small integers and shares it in other cases as well. (Out of curiosity, I just checked the code (header) again. Small ints are cached in tstate->interp->small_ints. 0 and 1 are even more special and are stored globally in _PyLong_Zero and _PyLong_One. All new creations of ints are via PyLong_FromLong and that one first checks if it is a small integer and cached.)

Given this background, if you know you have an int object, you could say that the check x is 0 should be safe, right? Also, you could derive that 0 is 0 should always be True, right? Or is this an implementation detail of CPython and other interpreters do not follow this? Which interpreter does not follow this?

Despite this more generic question (which I'm just curious about), consider this more specific (example) code:

def sum1a(*args):
    y = 0
    for x in args:
        if y is 0:
            y = x
        else:
            y = y + x
    return y

Vs:

def sum1b(*args):
    y = 0
    for x in args:
        if y == 0:
            y = x
        else:
            y = y + x
    return y

Vs:

def sum1c(*args):
    y = None
    for x in args:
        if y is None:
            y = x
        else:
            y = y + x
    if y is None:
        return 0
    return y

Vs:

def sum2(*args):
    y = 0
    for x in args:
        y = y + x
    return y

The reason I would sometimes prefer sum1* over sum2 is that depending on the library, sum1* can really be more efficient. E.g. if the argument is a Numpy/TensorFlow/PyTorch array, you really would save a (potentially costly) operation here.

The reason I would prefer sum1a over sum1b is that sum1b would break on certain inputs. E.g. if the input is a Numpy array, this would not work.

Of course, you could use sum1c instead of sum1a. However, sum1a is shorter. So this is nicer?

If the answer to the original question is that this should always work, and if you agree that sum1a is the best option then, how would you get rid of the warning? Is there a simple workaround? In general, I can see that the warning can be useful. So I would not want to disable it completely. I just want to disable it for this specific statement.

Maybe I could wrap it up in a function:

def is_(a, b):
    return a is b

And then just use if is_(y, 0): .... Does this work? Is that a good idea?

like image 588
Albert Avatar asked Jun 03 '20 14:06

Albert


People also ask

Is 0 == False in Python?

The Python Boolean type is one of Python's built-in data types. It's used to represent the truth value of an expression. For example, the expression 1 <= 2 is True , while the expression 0 == 1 is False . Understanding how Python Boolean values behave is important to programming well in Python.

Why does Python not return 0 true?

By default, an object is considered true unless its class defines either a bool() method that returns False or a len() method that returns zero, when called with the object. Here are most of the built-in objects considered false: Constants defined to be false: None and False.

Does 0 evaluate to False in Python?

The Python bool() built-in function evaluates the Truthiness of an object. Values resolved to 0 are evaluated as False whereas anything else is evaluated as True. The common case of Python's bool() function is the conversion of values such that they can be evaluated in conditional statements.

What number is true in Python?

Numbers. In Python, the integer 0 is always False , while every other number, including negative numbers, are True . In fact, under the hood, bool eans inherit from int egers.


1 Answers

No, it isn't. Case in point the Rust implementation for Python returns False:

>>>>> 0 is 0
False

and this is not wrong, though I expect this to change in future versions (it has!).

is calls id who's only stipulation is that the id returned is unique and constant for a given object. Whether the source code representation for a number (0 here) maps to a distinct object or not is up for the implementation to define.

like image 54
Dimitris Fasarakis Hilliard Avatar answered Oct 04 '22 07:10

Dimitris Fasarakis Hilliard