Remember the walrus operator
MP 136: I don't use it often, but I keep coming back to it.
The walrus operator was introduced in Python 3.8, back in 2019. I haven't used it often over the last five years, but occasionally I find myself writing some code that looks a little verbose, and then I remember the walrus operator exists. I've decided not to use it about as many times as I've used it, but it's worth considering in situations where it's relevant.
If you've never heard of the walrus operator, or have heard of it but don't recall the specifics, take a moment to refresh yourself and keep it in mind when it applies to your work.
What's in a name?
The walrus operator is an assignment expression, implemented with the symbol :=
. It assigns a value to a variable, and immediately returns that value as well. This is in contrast with the assignment operator =
which assigns a value to a variable, but doesn't return anything.
It's called the walrus operator because the symbol looks like the eyes and tusks of a walrus:

Life without walruses
Let's first look at an example that doesn't use the walrus operator. I want to use an existing username if one exists, but set a default username if it doesn't exist.
We'll start with a configuration object, which can have a username assigned to it:
class Config: def __init__(self): self.username = "" self.email = "" config = Config()
This is a small class called Config
, which collects information about a user's account. It has two fields, username
and email
. An instance of the class, config
, is created in this file as well.
Now let's use that config
object in a main file:
from utils import config username = config.username if not username: username = "default_user" print(username)
In the main file, we want to work with the username. But we don't know if config.username
has been set, so we need a conditional block right after the assignment to username
. If username
is empty, we set its value to default_user.
This works:
$ python main.py default_user
Let's make sure it really works, by changing the value of config.username
in utils.py:
... config = Config() config.username = "eric"
We should see the custom username in the output:
$ python main.py eric
This works as well.
For a long time, this implementation felt a bit awkward. We're assigning a value to a variable, and then immediately checking if that was a meaningful assignment. There are a couple ways to do this; here's another common approach:
if config.username: username = config.username else: username = "default_user"
Here we're checking if config.username
has been set, and using its value if it has. Otherwise, we're using default_user. This is a longer construct, and it has the same issue of evaluating config.username
twice in order to use it.
This is a common pattern, so Python developers decided to introduce an operator that collapses the inspection and assignment operations into one step.
Life with walruses
Here's what the main file looks like, using the walrus operator:
from utils import config if not (username := config.username): username = "default_user" print(username)
This version says, "assign the value of config.username
to username
, and also return the assigned value". If you use a simple equal sign here, you'll get a syntax error.
This version is shorter, which is nice, but there's something more important than just reducing the amount of code. In this implementation, we're only evaluating config.username
once. One of the goals of implementing the walrus operator was to reduce the need to evaluate an expression multiple times in common scenarios like this.
Poking at expressions
I started to understand the walrus operator better after looking at just the expression itself. Here's a simple assignment operation, run in a terminal session:
>>> user = "eric" >>> user 'eric'
The first statement assigns the value eric to user
. However, notice that there's no output associated with the assignment operation itself. The assignment operator =
assigns a value to a variable, but it doesn't return anything.
Contrast that with the walrus operator:
>>> (user := "eric") 'eric' >>> user 'eric'
Here the assignment expression assigns the value eric to user
, but it also returns that value immediately. The walrus operator is useful in conditional statements, but it's not tied to that context. At its heart, it's an assignment operation that also returns the value being assigned.
The walrus operator is an assignment operation that returns the value being assigned.
A real-world example
The walrus operator, even more than many other Python structures, needs to be examined in the context of real-world use cases in order to understand when it should be used. There are plenty of situations where it makes code shorter and more readable. But there are also many situations where it obscures the underlying logic, and you're better off with more verbose but readable code.
I was reminded of the walrus operator when building a plugin for django-simple-deploy, targeting VPS providers such as Digital Ocean and Hetzner. At one point in the deployment process, the plugin needs to SSH into the server. There are three different usernames that could be used: root
if it's a brand new server; a username provided by the user through an environment variable, or a default username that the plugin provides.
Here's the specific block where I ended up using the walrus operator:
def set_server_username(): ... if (username := os.environ.get("DO_DJANGO_USER")): # Use this custom username. dsd_config.server_username = username plugin_utils.write_output(f" username: {username}") return # No custom username. Try to connect with default username. ...
This block pulls the value of the environment variable DO_DJANGO_USER
, and assigns it to username
. If that name is anything other than an empty string, the conditional expression will evaluate to True
and this block will execute. If it's an empty string, it will evaluate to False
and we'll move to the next block, focusing on the default username.
The original code looked like this:
def set_server_username(): ... username = os.environ.get("DO_DJANGO_USER") if username: # Use this custom username. dsd_config.server_username = username plugin_utils.write_output(f" username: {username}") return # No custom username. Try to connect with default username. ...
Here username
is set using just the equal sign. Then in the next line, that value is examined to see if a username was provided. (You can see the full context here.)
This code is very much a work in progress, and I'm not sure if I'll keep the walrus operator in or not. If you have a preference for the second version, there are plenty of experienced Python programmers who would completely agree with you.
Conclusions
There are many features of Python that aren't required, but allow for cleaner and more concise structures if you're aware of them. As you gain experience with Python, it's worth becoming familiar with those structures. You'll be able to use them when appropriate in your own codebases, and you'll recognize them when you see them in code that others have written.
The walrus operator sometimes makes code simpler and more readable, and sometimes makes it shorter but less readable. Make your decisions about using it based on the specific context you're working in, not just whether it works syntactically or not.
If you want to read more about the walrus operator, the short overview in the original Python 3.8 release notes is worth reading. The actual documentation is really short; it's probably less than a page if you print it out. If you want an in-depth discussion then PEP 572, which proposed the walrus operator, is still worth skimming.