Walrus Operator in Python 3.8
Intro
Today, I would like to share a neat introduced in Python3.8 - the walrus operator. It sparked quite a bit of discussion before ultimately being accepted. 🤔️
The power of the walrus operator lies in turning an assignment statement into an assignment expression. You may be wondering: what exactly is the difference between a statement and an expression?
Expression vs Statement
In programming languages, you may encounter many different constructs. Broadly, they can be divided into two categories - expressions and statements. An expression is evaluated and produces a value, whereas a statement performs an action and does not return anything.
In Python, assignment is a statement with no return value. For example
print(x = 5)
The output is shown as follows.
Traceback (most recent call last):
File "main.py", line 1, in <module>
print(x = 5)
~~~~~^^^^^^^
TypeError: print() got an unexpected keyword argument 'x'
In C/C++, the assignment is an expression that will return the assigned value. For example
#include <iostream>
using namespace std;
int main() {
int a;
cout << (a = 42) << "\n";
}
The output is
42
The Syntax
The syntax is simple and intuitive: replace = with :=.
<NAME> := <EXPR>
To prevent misuse of this neat feature, <NAME> must be a simple variable name. That means you cannot place a list item (e.g., some_list[some_idx]) or an object attribute (e.g., some_instance.some_field) on the left-hand side of :=.
The semantics
The evaluation rules of <NAME> := <EXPR> are as follows
- Evalute
<EXPR>and obtain its value. - Assign that value to
<NAME>. - The evaluated value becomes the result of the entire expression.
Note that the precedence of := is higher than ,, but lower than most other operators. As a result, you may need to add the parentheses where appropriate.
When to use
One of the most valuable use cases is binding the return value of a function that may return None within control structures
- If the return value is
None, nothing happens - IF the return value is not
None, you can directly use the bound variable.
Before the walrus operators, most developers would first assign the return value using =, and then check whether it is None. For example
may_be_none = foo(....)
if may_be_none:
...
else:
...
However, we can merge them with the walrus operator.
if maybe_none := foo():
...
else:
...