Python walrus operator

By Martin McBride, 2025-02-04

Categories: python python language


Python 3.8 introduced the walrus operator, a feature that continues to create confusion and annoyance in equal measure. In this short article, we will try to understand what it is all about.

Expressions, statements and assignment

In programming, we use the term expression to describe a short piece of code that returns a value. For example, this expression returns the sum of a and b:

a + b

A statement is a short piece of code that has an effect but does not return a value. For example, this del statement removes element 2 from list k:

del k[2]

Since this is a statement, it does not return a value. This makes it illegal to use a statement where a value is required. For example:

print(a + b)
print(del k[2])

This code won't even compile. The second line gives a syntax error, because print requires a value but del is a statement.

When it comes to assignments, things get a bit more interesting. Here is a typical assignment:

c = a + b

This evaluates the expression a + b and assigns it to variable c. In Python, an assignment is a statement, so it doesn't return a value.

This was a deliberate choice when Python was created, But many other languages, before and after Python, have made the opposite choice. C, C++, Java, and Javascript, to name a few, all treat assignment as an expression. This allows us to do useful things like this:

x = y = z = 0   # Sets x, y and z to 0 - but not allowed!

This is possible in many languages but gives a syntax error in Python. That is because z = 0 is a statement, so there is no value created to assign to y or x.

Enter the walrus operator

While this has never been a major problem for most people, there are a few quite compelling use cases where the ability to use assignment as an expression could be very useful in ways that cannot be easily replicated without it.

These cases most certainly don't justify a wholesale change to make all assignments behave as expressions, but instead, a new operator was introduced. This takes the form :=, informally called the walrus operator (the colon represents the walrus's eyes, and the equals sign its teeth). It allows us to do things like this (although it is arguable whether this usage is beneficial):

if x := a:              # Sets x equal to a and also tests a
    print("a is true")

More formally these are called assignment expressions.

When to use the walrus operator

Although many languages generally treat assignments as expressions, Python traditionally does not. This makes the walrus operator a slightly usual addition to the language, and as such it is probably best to use it sparingly.

Some developers will choose not to use it at all, which is fair enough, Python survived for almost 30 years without it. But it exists, and you might well encounter other peoples' code, so it cannot be ignored altogether.

If you are undecided, here are perhaps the most compelling cases for its use. First, it can be used inside a list comprehension. In this example, we have a list of strings, and we want to create a list of the lengths of all the strings with length greater than one:

s = ["abc", "", "def", "g", "xy"]
l = [y for x in s if (y := len(x)) > 1]

Without using the walrus operator we would have the choice of two less optimal solutions. One would be to call len twice:

s = ["abc", "", "def", "g", "xy"]
l = [len(x) for x in s if len(x) > 1]

The other would be to create an intermediate list of lengths and then filter that.

s = ["abc", "", "def", "g", "xy"]
t = [len(x) for x in s]
l = [x for x in t if x > 1]

If we were using a very expensive function, rather than len, and if the list was very long, neither of those solutions would be good.

The syntax can also be used effectively in a while loop if we want to test a function return before using the returned value within the loop. For example, this code calls f() repeatedly and prints the result, until the function returns a false value:

while (r := f()):
    print(r)

Doing this without the walrus operator is somewhat more clumsy:

r = f()
while r:
    print(r)
    r = f()

Summary

The walrus operator divides opinion, but it is here and you will most likely encounter it at some point. You need to at least be aware of it, but if you keep an open mind you might even find it useful once in a while.



Join the GraphicMaths Newletter

Sign up using this form to receive an email when new content is added:

Popular tags

adder adjacency matrix alu and gate angle area argand diagram binary maths cartesian equation chain rule chord circle cofactor combinations complex modulus complex polygon complex power complex root cosh cosine cosine rule cpu cube decagon demorgans law derivative determinant diagonal directrix dodecagon eigenvalue eigenvector ellipse equilateral triangle euler eulers formula exponent exponential exterior angle first principles flip-flop focus gabriels horn gradient graph hendecagon heptagon hexagon horizontal hyperbola hyperbolic function hyperbolic functions infinity integration by parts integration by substitution interior angle inverse hyperbolic function inverse matrix irrational irregular polygon isosceles trapezium isosceles triangle kite koch curve l system line integral locus maclaurin series major axis matrix matrix algebra mean minor axis nand gate newton raphson method nonagon nor gate normal normal distribution not gate octagon or gate parabola parallelogram parametric equation pentagon perimeter permutations polar coordinates polynomial power probability probability distribution product rule proof pythagoras proof quadrilateral radians radius rectangle regular polygon rhombus root sech segment set set-reset flip-flop sine sine rule sinh sloping lines solving equations solving triangles square standard curves standard deviation star polygon statistics straight line graphs surface of revolution symmetry tangent tanh transformation transformations trapezium triangle turtle graphics variance vertical volume volume of revolution xnor gate xor gate