Image by Author | Created on Snappify
In Python, if you want to assign values to variables within an expression, you can use the Walrus operator :=. While x = 5
is a simple variable assignment, x := 5
is how you’ll use the Walrus operator.
This operator was introduced in Python 3.8 and can help you write more concise and potentially more readable code (in some cases). However, using it when not necessary or more than necessary can also make code harder to understand.
In this tutorial, we will explore both the effective and the not-so-effective uses of the Walrus operator with simple code examples. Let’s get started!
How and When Python’s Walrus Operator is Helpful
Let’s start by looking at examples where the walrus operator can make your code better.
1. More Concise Loops
It’s quite common to have loop constructs where you read in an input to process within the loop and the looping condition depends on the input. In such cases, using the walrus operator helps you keep your loops cleaner.
Without Walrus Operator
Consider the following example:
data = input("Enter your data: ")
while len(data) > 0:
print("You entered:", data)
data = input("Enter your data: ")
When you run the above code, you’ll be repeatedly prompted to input a value so long as you input a non-empty string.
Note that there is redundancy. You initially read in the input to the data
variable. Within the loop, you print out the entered value and prompt the user for input again. The looping condition checks if the string is non-empty.
With Walrus Operator
You can remove the redundancy and rewrite the above version using the walrus operator. To do so, you can read in the input and check if it is a non-empty string—all within the looping condition—using the walrus operator like so:
while (data := input("Enter your data: ")) != "":
print("You entered:", data)
Now this is more concise than the first version.
2. Better List Comprehensions
You’ll sometimes have function calls within list comprehensions. This can be inefficient if there are multiple expensive function calls. In these cases, rewriting using the walrus operator can be helpful.
Without Walrus Operator
Take the following example where there are two calls to the `compute_profit` function in the list comprehension expression:
- To populate the new list with the profit value and
- To check if the profit value is above a specified threshold.
# Function to compute profit
def compute_profit(sales, cost):
return sales - cost
# Without Walrus Operator
sales_data = [(100, 70), (200, 150), (150, 100), (300, 200)]
profits = [compute_profit(sales, cost) for sales, cost in sales_data if compute_profit(sales, cost) > 50]
With Walrus Operator
You can assign the return values from the function call to the `profit` variable and use that the populate the list like so:
# Function to compute profit
def compute_profit(sales, cost):
return sales - cost
# With Walrus Operator
sales_data = [(100, 70), (200, 150), (150, 100), (300, 200)]
profits = [profit for sales, cost in sales_data if (profit := compute_profit(sales, cost)) > 50]
This version is better if the filtering condition involves an expensive function call.
How Not to Use Python’s Walrus Operator
Now that we’ve seen a few examples of how and when you can use Python’s walrus operator, let’s see a few anti-patterns.
1. Complex List Comprehensions
We used the walrus operator within a list comprehension to avoid repeated function calls in a previous example. But overusing the walrus operator can be just as bad.
The following list comprehension is hard to read due to multiple nested conditions and assignments.
# Function to compute profit
def compute_profit(sales, cost):
return sales - cost
# Messy list comprehension with nested walrus operator
sales_data = [(100, 70), (200, 150), (150, 100), (300, 200)]
results = [
(sales, cost, profit, sales_ratio)
for sales, cost in sales_data
if (profit := compute_profit(sales, cost)) > 50
if (sales_ratio := sales / cost) > 1.5
if (profit_margin := (profit / sales)) > 0.2
]
As an exercise, you can try breaking down the logic into separate steps—within a regular loop and if conditional statements. This will make the code much easier to read and maintain.
2. Nested Walrus Operators
Using nested walrus operators can lead to code that is difficult to both read and maintain. This is particularly problematic when the logic involves multiple assignments and conditions within a single expression.
# Example of nested walrus operators
values = [5, 15, 25, 35, 45]
threshold = 20
results = []
for value in values:
if (above_threshold := value > threshold) and (incremented := (new_value := value + 10) > 30):
results.append(new_value)
print(results)
In this example, the nested walrus operators make it difficult to understand—requiring the reader to unpack multiple layers of logic within a single line, reducing readability.
Wrapping Up
In this quick tutorial, we went over how and when to and when not to use Python’s walrus operator. You can find the code examples on GitHub.
If you’re looking for common gotchas to avoid when programming with Python, read 5 Common Python Gotchas and How to Avoid Them.
Keep coding!
Bala Priya C is a developer and technical writer from India. She likes working at the intersection of math, programming, data science, and content creation. Her areas of interest and expertise include DevOps, data science, and natural language processing. She enjoys reading, writing, coding, and coffee! Currently, she’s working on learning and sharing her knowledge with the developer community by authoring tutorials, how-to guides, opinion pieces, and more. Bala also creates engaging resource overviews and coding tutorials.