Contents

Walrus Operator in Python 3.8

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?

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 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 evaluation rules of <NAME> := <EXPR> are as follows

  1. Evalute <EXPR> and obtain its value.
  2. Assign that value to <NAME>.
  3. 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.

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:
    ...