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:
-
Python 101 – How to Work with Images
-
Python 101 – Documenting Your Code
-
Python 101: An Intro to Working with JSON
-
Python 101 – Creating Multiple Processes