Using the Python Walrus Operator

Content:

The walrus operator, introduced in Python 3.8, is a new assignment operator which assigns variables as part of a larger expression.

The syntax for this operator is :=. It gained the unofficial ‘walrus’ moniker due to the resemblance of the syntax to the eyes and tusks of a walrus.

When used correctly, the walrus operator can include readability and reduce code complexity.

Why a New Operator?

Unlike some other programming languages, such as PHP, the Python = operator does not have a result. It is solely an expression, to assign a value to a variable.

Because of this, it’s not possible to use variable assignment as part of larger statements, such as if statements.

For example, the following code in PHP

if ($name = get_name()) {
    echo $name
}

would not work correctly if converted directly to Python.

if name = get_name():    # syntax error
    print(name)

The walrus operator introduces an assignment operator which does return a result. This makes it possible to do both the assignment, and evaluation, in one step.

If Statements

A common usage for the walrus operator is to simplify if statements.

Rewriting the previous example, the following is the pre-3.8 way of writing the same statement in Python.

name = get_name()

if name:
    print(name)

The assignment is done first, then the result is evaluated in the if statement.

Using the walrus operator, we can assign the value and evaluate the if statement in one step.

if name := get_name():
    print(name)

Not only does this look cleaner, but it narrows the scope of the name variable to the if statement. It’s unclear in the previous code that name is only intended to be used inside the if statement. Narrowing the scope of variables makes their intent more obvious.

While Loops

The walrus operator can be used in while loops.

while (name = input("Enter your name: ")) != '':
    print(f"Hello, {name}")

In this example, the input is checked to ensure a value has been entered. If so, the value is printed. If not, the user will be prompted once again.

Consider the pre-3.8 alternative.

name = input("Enter your name: ")

while name != '':
    print(f"Hello, {name}")
    input("Enter your name: ")

Here, the input block has to be duplicated, both inside and outside of the while loop.

Not the most practical example, but another demonstration of the power of the walrus operator.

Limitations

There are a few limitations to the walrus operator, which you’ll need to keep in mind.

  • It can only be used in a ‘positive’ if statement – the following is not allowed:
if not name := get_name():    # syntax error
    print(name)
  • It can’t be used to assign object properties.
user.name := get_name()    # syntax error
  • It can’t be used to assign indexed names.
user['name'] := get_name()    # syntax error
  • It can’t be used when unpacking values.
firstname, lastname := get_name()    # syntax error

Benefits of a Separate Operator

At this point, you might be asking: why use a separate operator? If the = operator in other languages is used for both assignment and evaluation, why doesn’t Python do the same?

The motivation for using a separate operator is the clarity it adds to the code. The intention of the programmer is explicit, making bugs more obvious.

For example, consider the following PHP code. The intention of this code is to compare two values, and print a string if they are the same.

if ($x = $y) {
    echo "x equals y"
}

What happens if $x and $y are not the same value?

Unfortunately, this code has a bug. Rather than comparing the values (using ==), it instead assigns the value of $y to $x. However, because = also evaluates expressions, the if statement returns true. There’s no indication that this bug exists, because the statement is perfectly valid.

It would be relatively easy for a developer to miss an = by mistake. In Python, this kind of bug would not occur.

if x = y:    # syntax error
    print("x equals y")

This is a syntax error, which will be flagged when trying to run the code. The developer then has the change to correct the syntax to match their intention.