Python 101 - Assignment Expressions

Assignment expressions were added to Python in version 3.8. The general idea is that an assignment expression allows you to assign to variables within an expression.

The syntax for doing this is:

NAME := expr

This operator has been called the "walrus operator", although their real name is "assignment expression". Interestingly, the CPython internals also refer to them as "named expressions".

You can read all about assignment expressions in PEP 572. Let's find out how to use assignment expressions!

Using Assignment Expressions

Assignment expressions are still relatively rare. However, you need to know about assignment expressions because you will probably come across them from time to time. PEP 572 has some good examples of assignment expressions.

# Handle a matched regex
if (match := pattern.search(data)) is not None:
    ...

# A more explicit alternative to the 2-arg form of iter() invocation
while (value := read_next_item()) is not None:
    ...

# Share a subexpression between a comprehension filter clause and its output
filtered_data = [y for x in data if (y := f(x)) is not None]

In these 3 examples, you are creating a variable in the expression statement itself. The first example creates the variable match by assigning it the result of the regex pattern search. The second example assigns the variable value to the result of calling a function in the while loop’s expression. Finally, you assign the result of calling f(x) to the variable y inside of a list comprehension.

It would probably help to see the difference between code that doesn't use an assignment expression and one that does. Here's an example of reading a file in chunks:

with open(some_file) as file_obj:
    while True:
        chunk_size = 1024
        data = file_obj.read(chunk_size)
        if not data:
            break
        if 'something' in data:
            # process the data somehow here

This code will open up a file of indeterminate size and process it 1024 bytes at a time. You will find this useful when working with very large files as it prevents you from loading the entire file into memory. If you do, you can run out of memory and cause your application or even the computer to crash.

You can shorten this code up a bit by using an assignment expression:

with open(some_file) as file_obj:
    chunk_size = 1024
    while data := file_obj.read(chunk_size):
        if 'something' in data:
            # process the data somehow here

Here you assign the result of the read() to data within the while loop's expression. This allows you to then use that variable inside of the while loop's code block. It also checks that some data was returned so you don't have to have the if not data: break stanza.

Another good example that is mentioned in PEP 572 is taken from Python's own site.py. Here's how the code was originally:

env_base = os.environ.get("PYTHONUSERBASE", None)
if env_base:
    return env_base

And this is how it could be simplified by using an assignment expression:

if env_base := os.environ.get("PYTHONUSERBASE", None):
    return env_base

You move the assignment into the conditional statement's expression, which shortens the code up nicely.

Now let's discover some of the situations where assignment expressions can't be used.

What You Cannot Do With Assignment Expressions

There are several cases where assignment expressions cannot be used.

One of the most interesting features of assignment expressions is that they can be used in contexts that an assignment statement cannot, such as in a lambda or the previously mentioned comprehension. However, they do NOT support some things that assignment statements can do. For example, you cannot do multiple target assignment:

x = y = z = 0  # Equivalent, but non-working: (x := (y := (z := 0)))

Another prohibited use case is using an assignment expression at the top level of an expression statement. Here is an example from PEP 572:

y := f(x)  # INVALID
(y := f(x))  # Valid, though not recommended

There is a detailed list of other cases where assignment expressions are prohibited or discouraged in the PEP. You should check that document out if you plan to use assignment expressions often.

Wrapping Up

Assignment expressions are an elegant way to clean up certain parts of your code. The feature's syntax is kind of similar to type hinting a variable. Once you have the hang of one, the other should become easier to do as well.

In this article, you saw some real-world examples of using the "walrus operator". You also learned when assignment expressions shouldn't be used. This syntax is only available in Python 3.8 or newer, so if you happen to be forced to use an older version of Python, this feature won't be of much use to you.

Related Reading

This article is based on a chapter from Python 101, 2nd Edition, which you can purchase on Leanpub or Amazon.

If you'd like to learn more Python, then check out these tutorials:

Copyright © 2021 Mouse Vs Python | Powered by Pythonlibrary