Python’s and
operator performs the logical AND operation that returns True
if both operands evaluate to True
. The operator performs an optimization called short-circuiting, so if the first operand evaluates to True
, it returns the second operand; and if the first operand evaluates to False
, it returns False
without further evaluating the second operand.
As you read through the article, you can also watch my video for supporting explanations:
Python and Operator – on Booleans
Here’s the result of the and
operator when applied to Boolean operands:
First Operand A | Second Operand B | A and B |
---|---|---|
False | False | False |
False | True | False |
True | False | False |
True | True | True |
You can see those examples in the following script:
>>> False and False False >>> False and True False >>> True and False False >>> True and True True
Python and Operator – on Integers
You can also apply the and operator to integers:
First Operand A | Second Operand B | A and B |
---|---|---|
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
The same can be seen in the following Python script:
>>> 0 and 0 0 >>> 0 and 1 0 >>> 1 and 0 0 >>> 1 and 1 1
Python and Operator – on Objects
Interestingly, you can also apply the logical AND operator on arbitrary Python objects. The base idea is the “truthiness” of Python objects, i.e., every Python object has an associated Boolean value as determined by the __bool__()
magic method.
In the following code, you create a custom class called My_Obj
and use the “and
” operator on instances of this class.
>>> class My_Obj: None >>> My_Obj() and My_Obj() <__main__.My_Obj object at 0x0000025108D897F0> >>> 0 and My_Obj() 0 >>> 1 and My_Obj() <__main__.My_Obj object at 0x0000025108D897F0>
You may wonder why some of the outputs are as strange-looking as they are. The reason is simple: every custom object has an associated implicit Boolean value:
>>> bool(My_Obj()) True
If the first operand of the and operation evaluates to True
, Python performs the short-circuiting optimization, i.e., it immediately returns the second operand. This makes sense because the second operand logically determines the overall result (see tables below where the first operand is True
).
First Operand A | Second Operand B | A and B |
---|---|---|
True | False | False |
True | True | True |
Thus, it is not needed to even evaluate the second operand—and Python simply returns it without modification. That’s why the result of the and operation can be a custom object instead of a Boolean value.
Python and Operator – on Lists
You can apply the and
operator on arbitrary objects, including lists. Every list object has an associated Boolean value as determined by the bool(list)
method—all lists evaluate to True
except the empty list. If you apply the and
operator to two lists, Python returns the second list if both lists are non-empty (due to short-circuiting), and the empty list otherwise.
>>> [1, 2, 3] and [4, 5, 6] [4, 5, 6] >>> [] and [4, 5, 6] [] >>> [1, 2, 3] and [] [] >>> [] and [] []
Python and Operator Short Circuit
Short-circuiting is a common optimization in programming languages that use the following observation: if the first operator evaluates to False
, the whole and
expression must evaluate to False
too. Thus, it is not needed to evaluate subsequent operands to know the result of the overall logical expression. Only if the first operand is True
, it moves further to the second operand—and, potentially, the third and so on. This can save significant time when evaluating complicated logical expressions.
A minimal example of short-circuiting on the and
operator is shown here:
>>> False and print('Am I evaluated?') False >>> True and print('Am I evaluated?') Am I evaluated?
We use a simple trick to check if the second operand is evaluated or not due to the short-circuiting optimization—the second operand is a print()
statement that always returns None
but generates visible side-effects when executed. You can see that in the first example, it is not evaluated because the first operand already determines the result of the whole expression. But in the second example, it is evaluated because the first operand does not provide a conclusive answer on the result of the overall expression.
Python and Operator vs &
Python’s “and
” operator performs a logical AND operation that returns True
if both operands are True
. Python’s “&
” symbol is a bitwise operator that works on the bit representations of the operands and performs a bit by bit operation. So, “and
” tests whether both operands are logically True
whereas “&
” performs bitwise AND operation on the operands.
When considering only a single bit, semantically, such as when comparing Booleans, the operators are the same:
>>> True and True True >>> True & True True
However, the difference becomes apparent if you use integer operands:
>>> 32 and 16 16 >>> 32 & 16 0
The first expression 32 and 16
determines that the integer value 32 results in a Boolean True
, so it returns the second operand 16 as it performs the short-circuiting optimization.
The second expression 32 & 16 operates on the bit representations 10000 (decimal 32) and 01000 (decimal 16) and performs bit-wise AND. As all i-th bit positions are different, the result is 0:
First Operand A | 1 | 0 | 0 | 0 | 0 | 0 |
Second Operand B | 0 | 1 | 0 | 0 | 0 | 0 |
A & B | 0 | 0 | 0 | 0 | 0 | 0 |
Similarly, let’s have a look at another example to showcase the bitwise and operator:
>>> 31 & 15 15
You can see this in the following visualization:
First Operand A | 1 | 1 | 1 | 1 | 1 |
Second Operand B | 0 | 1 | 1 | 1 | 1 |
A & B | 0 | 1 | 1 | 1 | 1 |
The decimal representation of the bit sequence 01111 is 15.
Python and Operator Evaluation Order
Python evaluates the left before the right operand. It uses short-circuiting when evaluating expressions involving the logical and
or or
operators, so it doesn’t evaluate the second operand unless it is necessary to determine the result. The logical and
takes precedence before the logical or
.
In the following example, you see that the “and” operator is evaluated first because it has precedence over the “or” operator.
>>> False and False or True True >>> (False and False) or True True >>> False and (False or True) False
The same precedence can be seen here:
>>> True or False and False True >>> (True or False) and False False >>> True or (False and False) True
This also rules out what many people wrongly assume—that there’s a first-comes-first-serve operator precedence. In this example, the “and” operator is evaluated first even though it comes later.
Python and Operator in If Condition
If you want to use the logical AND operator in an if condition, use the keyword and
instead of the double &&
symbol you may know as the logical AND from Java or C++. For example, if A and B
would be correct whereas if A && B
would be incorrect.
Here’s the correct use of the logical AND in an if condition:
# YES! if 2+2 == 4 and 2-2 == 0: print('YES!')
The result of this code snippet is 'YES!'
.
Here’s the wrong way of doing it as a C++ or Java coder going Python:
# NO! if 2+2 == 4 && 2-2 == 0: print('NO!')
The result of this code snippet is a SyntaxError
:
To resolve this, simply replace the faulty double symbol &&
with the correct keyword and
.
Logical Operators
Logical operators are shortcuts to perform Boolean comparisons, but can be used on integers and other objects as well.
Operator | Description | Example |
---|---|---|
and | Returns True if both operands are True , and False otherwise. | (True and True) == True |
or | Returns True if at least one of the two operands is True , and False otherwise. | (False or True) == True |
not | Returns True if the single operand is False , and False otherwise. | (not True) == False |