Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

can Python 'and' return None?

I am looking at some code which apparently runs, as nobody has complained about it, but am well confused by what they have written:

if a and b is not None:
    # do something

I have always thought of the 'and' operator as something which returns True or False, now am starting to doubt myself.. What else would it return, a number.. It is probably not pythonic, but am I missing something - how can someone write something like that?

like image 983
cardamom Avatar asked Dec 18 '22 19:12

cardamom


2 Answers

It means if a is Truthy and b is not None and not what you thought it meant i.e. a and b is Truthy

a = 999
b = None

if a and b is not None:
    print("a is True but b is None")
else:
    print("a is True and b is not None")
like image 101
DirtyBit Avatar answered Dec 28 '22 23:12

DirtyBit


According to [Python 3]: Operator precedence (emphasis is mine):

The following table summarizes the operator precedence in Python, from lowest precedence (least binding) to highest precedence (most binding).

...
and                                                 Boolean AND
not x                                               Boolean NOT
in, not in, is, is not, <, <=, >, >=, !=, ==        Comparisons, including membership tests and identity tests
...

The fact that is not comes after and, means that it will be evaluated before and (both might not be evaluated at all, due to lazy evaluation - thanks @NickA for the comment), so the expression is equivalent to (adding parentheses for clarity):

if a and (b is not None):

Also, according to [Python 3]: Truth Value Testing:

Any object can be tested for truth value, for use in an if or while condition or as operand of the Boolean operations below.

your if statement is perfectly OK (produces a bool).

Examples (using [Python 3]: class bool([x])):

>>> bool(0)
False
>>> bool(100)
True
>>> bool([])
False
>>> bool([0])
True
>>> bool(None)
False
>>> bool({})
False
>>> bool({1: 1})
True
>>> bool(None is not None)
False
>>> bool(1 is not None)
True
>>> bool(2 and 1 is not None)
True
like image 34
CristiFati Avatar answered Dec 29 '22 00:12

CristiFati