Python 3.8, controversially, introduced a new way of assigning values to variables — assignment expressions, otherwise known as the “walrus operator” (:=) due to it slightly resembling walrus tusks.

Image of a walrus with code overlaying the tusks

This new feature (and syntax) (see PEP 572 for details) allows us to assign and return a value in the same expression.

The simplest case would be this:

print(var := 'value')

This sets var to ‘value’ and also prints the value at the same time.

Use Cases for Assignment Expressions

We are now going to have a look at four use cases for the walrus operator that hopefully also demonstrate how it is used. Please remember: All of these things could be easily achieved without the new functionality.

1. Reusing Values from If-Statements

Let’s assume that we want to check the length of a list. If the list is longer than a given value, we want to print a warning and the length of the list.

values = [1, 2, 3, 4, 5, 6]

if (n := len(values)) > 5:
    print(f'The list is too long. It contains {n} values.')

Using the new syntax saves us from calling len() twice or from memorizing its output.

Similarly, we can use this to work with regular expressions very elegantly:

s = 'Hello World!'

if (matches := re.match('Hello', s)):
    print(matches.group(0))

2. Filtering in List Comprehensions

List comprehensions are fantastic and, especially in data science, extremely useful. In the past, if we wanted to quickly apply a filter during the construction of a list, we had to use a rather complicated lambda expression using map.

Now, using assignment expressions, we can easily drop in a filter function:

data = [10, 20, 30, 40]

def greater_10(x):
    if x > 10: 
        return x

[y for x in data if (y := greater_10(x)) is not None]

This expression, for each value, will use greater_10 as a filter and only append the value if the function does not return None.

3. Reading Within While-Loops

If we want to read a file (or stream), we usually utilize some conditional logic to break out of the while-loop if, for example, there is no more data to read. Using the walrus operator, we can streamline this process quite a bit:

# The file 'text' contains a string 'abc'
with open('text', 'r') as f:
    while c := f.read(1):
        print(c)

We can even make the condition more explit:

with open('text', 'r') as f:
    while (c := f.read(1)) != 'c':
        print(c)

This will only print as long as we are not reading ‘c’.

4. Reusing (Expensive) Values

Let’s go back to list comprehensions and assume that we have a function calculate(), which is computationally expensive and takes one value. Using the walrus operator syntax, we can easily reuse computed values in a list comprehension:

l = [x := calculate(x), x**2, x**4]

This, at least to me, is a cleaner solution than to store the value before reusing it.

P.S. Despite the fact that there has been controversy, I like the new feature. I believe that the walrus operator allows for some convenient solutions and actually is quite readable. However, maybe it’s just me being nostalgic given that my first language, Object Pascal (Delphi), used the := operator.