Python 3.8 Walrus Operator (Assignment Expression)

Rate this post

The release of Python 3.8 came with an exciting new feature: the Walrus Operator. It’s an assignment expression, or in simpler terms an assignment inside an expression.

Let’s dive into practice immediately and look at the following code:

users = [
            {'name': 'Alice', 'uid': 123, 'approved': True},
            {'name': 'Bob',   'uid': 298, 'approved': True},
            {'name': 'Cloe',  'uid': 342},
            {'name': 'Dain',  'uid': 498, 'approved': False},
            {'name': 'Elon',  'uid': 567, 'approved': True},
        ]

appr_count = 0      
for user in users:
    appr = user.get('approved')
    if appr:
        appr_count += 1
        print(appr)

print(appr_count)

We have a list of users whose data is represented in a dictionary. We want to count the number of approved users. The entry 'approved' is set to True if the user was approved. If the user wasn’t approved, the entry 'approved' can be False or absent.

Inside the for-loop we retrieve the value of 'approved' from the user dictionary first and assign it to the variable appr. Second, we use the if-statement to check if the value of appr is either True or False/None.
Using the Walrus Operator we can merge these two steps into one so that our loop would look like this:

for user in users:
    if appr := user.get('approved'):
        appr_count += 1
        print(appr)

Try It Yourself:

Now you can see how we the assignment and the if-expression have become one single step in our code. And this is why it’s called assignment expression.

Applications

The Walrus Operator has a wide range of applications which we want to examine in the following paragraphs.

Walrus Operator with Regex


Regular Expressions are a powerful tool in programming. We even wrote an entire book about them! (Check out “The Smartest Way to Learn Python Regex”.)

Together with Regular Expressions the Walrus Operator can be used to check and assign a match in one line.

Here is the code:

import re

pattern = r'ab+'
text = 'bbbaabbba'

if (match := re.search(pattern, text)) is not None:
    # process the match object
    print(match.span())
else:
    print('no match')

I suggest, as an exercise, you try to rewrite the code from above without the walrus operator.

If you need a hint, check the first paragraph of this article.

Read File byte-wise Using the Walrus Operator

The Walrus Operator can be nicely used for reading chunks of data byte-wise from a file.

with open('data.txt', 'r') as file:
    # 1024 = number of bytes to return
    while chunk := file.read(1024):
        print(chunk)

In this case it would be more complicated to rewrite the code without the Walrus Operator since it would require a while True loop and inside the
loop you’d have to check what you read. If the file.read() method returns None you break out of the for-loop, else you process the chunk. So, here the Walrus Operator comes in very handy.

Walrus Operator in List Comprehensions

The Walrus Operator can be used in list comprehensions so that a function doesn’t have to be called multiple times.

# expensive function
f = lambda x: x**3

data = [1, 2, 3, 4, 5]
filtered_data = [y for x in data if (y := f(x)) > 25]

In the if-statement of the list comprehension we call function f and assign the value to y if the result of f(x) makes the condition become True.

If we want to add the result of f(x) to the list we’d have to call f(x) again without the Walrus Operator or write a for-loop where we can use a temporary variable.

By using the Walrus Operator in a list comprehension we can avoid multiple function calls and reduce the lines of code.

Reuse a Value That Is Expensive to Compute

I consider this application of the Walrus Operator rather a curiosity but for the sake of completeness I’d like to mention it. In this case it reduces the number of lines of code that you have to write by one.

Instead of writing:

y = f(x)
data = [y, y**2, y**3]

you can shorten the code by using the Walrus Operator to one single line:

data = [y := f(x), y**2, y**3]

I don’t recommend this use of the Walrus Operator since it reduces readability. It’s very easy now to miss the point where the initial value of y gets computed.

Conclusion

The Walrus Operator is a cool new feature but don’t over-use it. As we have seen in the examples above, it helps to write code faster because we need less code. However, readability is also very important since code is written only once but read multiple times. If you save a minute writing your code but then spend two hours debugging it, it’s clearly not worth it.

This ambiguity has also sparked controversy around the Walrus Operand and in my opinion, as many times in life, the middle way is the way to go.

Where to Go From Here?

Want to start earning a full-time income with Python—while working only part-time hours? Then join our free Python Freelancer Webinar.

It shows you exactly how you can grow your business and Python skills to a point where you can work comfortable for 3-4 hours from home and enjoy the rest of the day (=20 hours) spending time with the persons you love doing things you enjoy to do.

Become a Python freelancer now!