Introduction
The walrus operator (:=) is one of the features that was added in Python 3.8 (PEP 572). The walrus operator is called so because it kind of looks like the eyes and tusks of a walrus.
It is also called an assignment expression or named expression. In fact, the PEP 572 title uses the name assignment expressions and the CPython implementation references it as named expressions.
In this article, we will go through the syntax and how the Python walrus operator works with examples.
Walrus Operator Controversy
The introduction of the walrus operator into Python 3.8 is one of the reasons why Guido van Rossum stepped down from his position as BDFL (Benevolent Dictator For Life). See Guido’s reply below to why he stepped down as BDFL.
"The straw that broke the camel's back was a very contentious Python enhancement proposal, where after I had accepted it, people went to social media like Twitter and said things that really hurt me personally. And some of the people who said hurtful things were actually core Python developers, so I felt that I didn't quite have the trust of the Python core developer team anymore."
One of the reasons why the Python community & developers criticized this feature so much is that it failed to satisfy some of the guiding principles of Python as mentioned in Zen of Python. Also, the random people on the internet and Python core developers despised Guido’s decision of accepting PEP 572 which eventually led to his resignation as BDFL.
Whatever be the controversy, since it’s now officially part of Python, we will understand how we can make better use of this operator.
Walrus Operator
The syntax for the walrus operator is shown below. As you can see walrus operator helps you assign values to variables within an expression. Note that it returns the value of NAME.
NAME := expression
where
NAME: an identifier
expression: any valid un-parenthesized Python expression
The main reason for introducing this feature was to reduce the number of lines of code which in turn saves coding time for the programmers.
"Try to limit the use of the walrus operator to clean cases that reduce complexity and improve readability" - PEP 572
Let’s try to understand how to use the walrus operator with few examples.
Example 1 (walrus operator in if conditions)
Without walrus operator
We have written the same code in 2 ways without using the walrus operator below. Notice that we are calling the len() function twice in the first snippet and the second snippet has 4 lines of code.
# Without walrus operator
nums = [10, 20, 30, 40, 50]
if len(num):
print(f"There are {len(nums)} elements in the list")
nums = [10, 20, 30, 40, 50]
size = len(num)
if size:
print(f"There are {size} elements in the list")
With walrus operator
Let’s see how we can write the same coding using the walrus operator. We are calculating the length of the list and assigning it to the variable named size in the same line. As you have noticed, using the walrus operator we were able to reduce the number of lines and also avoided calling the len() function twice.
nums = [10, 20, 30, 40, 50]
if (size := len(num)):
print(f"There are {size} elements in the list")
Example 2 (walrus operator in while loop)
Without walrus operator
One of the best use-cases of the walrus operator is in an infinite while loop. The below example keeps asking you to enter the value until you type ‘quit’.
command = input("> ")
while command != "quit":
print("Your input:", command)
command = input("> ")
Without walrus operator
By using the walrus operator you are able to reduce the 4 lines of code into just 2 lines.
while (command := input(">> ")) != "quit":
print("Your input:", command)
Example 3 (walrus operator in for loop)
With walrus operator
Here is another example of walrus operating with for loop. Let’s say you have a list of 5 student names and their total marks (out of 600). You want to calculate the percentage and output only the students who scored above 70%. See the example below using the walrus operator.
students = [
{"name" : "Chetan", "marks" : 475},
{"name" : "Swathi", "marks" : 501},
{"name" : "Nikhil", "marks" : 584},
{"name" : "Salil", "marks" : 498},
{"name" : "Rajat", "marks" : 590},
]
for student in students:
if (percentage := ((student["marks"]/700)*100)) > 70:
print("{} has scored {:0.02f} % ".format(student["name"], percentage))
Without walrus operator
If you not using the walrus operator then you would have to add another line of code to calculate the percentage first and then use it in the if condition as shown below. With the walrus operator, you reduced a line of code and without adding any complexity to the code.
for student in students:
percentage = (student["marks"]/700)*100
if percentage > 70:
print("{} has scored {:0.02f} % ".format(student["name"], percentage))
Want to learn for-else and while-else in Python? Read our detailed blog post here.
Example 4 (walrus operator in list comprehension)
Without walrus operator
Here is an example using the list comprehension. In this example, sin() function is called twice.
# Without walrus operator
import math
[math.sin(x) for x in range(10) if math.sin(x) >= 0]
With walrus operator
Notice that by making use of the walrus operator we are calling math.sin() function only once instead of twice.
# With walrus operator
import math
[res for x in range(10) if (res:= math.sin(x)) >= 0]
I hope these 4 examples gave you some information on how you can start using the Walrus operator in your program. However, you need to follow certain rules when using the walrus operator. Let’s go through them in the next section
Read our comprehensive guide to list comprehensions in Python here.
Limitations of walrus operator
The walrus operator looks similar to an assignment (=) operator and has the lowest precedence. So, in order to avoid confusion, you need to follow certain rules when using the walrus operators. These are also mentioned under Exceptional Cases in PEP 572.
(1) Avoid using unparenthesized expressions at the top level of an expression statement.
The expression y:= my_func()
is an unparenthesized expression at the top which gives a syntax error. Though the parenthesized expression solves the problem, it is not recommended to avoid ambiguity and confusion.
def my_func(n=5):
return [i for i in range(n)]
y := my_func() # Syntax error
(y := my_func()) # No error, but not recommended
(2) Avoid using unparenthesized expression at the top level of the right side of an assignment expression.
z = y1 := my_func() # Syntax error
z = (y1 := my_func() ) # No error, but not recommended
(3) Avoid using unparenthesized assignment expressions as keyword arguments in a function call
my_func(n=x := 10) # Syntax error
my_func(n=(x := 10)) # No error, but not recommended
(4) Avoid using unparenthesized expressions at the top level of a function default value.
def my_func(n = x:=5): # Syntax Error
return [i for i in range(n)]
def my_func(n = (x:=5)): # No error, but not recommended
return [i for i in range(n)]
(5) Avoid using unparenthesized assignment expressions as annotations for arguments, return values, and assignments.
def my_func(n: x := 'this is annotation' = 5): # Error
print(n)
def my_func(n: (x := 'this is annotation') = 5): # No error, but not recommended
print(n)
(6) Avoid using unparenthesized assignment expressions in lambda functions.
lambda: x := 1 # Syntax Error
lambda: (x := 1) # No error, but not recommended
(7) Avoid using assignment expressions inside of f-strings. The : operator inside f-string literals indicates formatting options.
myStr = "Python Simplified"
f"{x:=myStr}" # ValueError: Invalid format specifier
f"{(x:=myStr)}" # No error, but not recommended
In nutshell, even though you can use parenthesized assignment expressions, avoid what we discussed in the above section. So, that way the code is readable without any confusion and ambiguity.
The walrus operator is also used extensively in the Python standard libraries such as copy, datetime, decimal modules, etc. You can check here for more details on this.
Conclusion
In this article, we talked about what is walrus operator, its syntax, and how to use it using simple examples. The walrus operator is very helpful in many situations where you can reduce the number of lines of code. Note that sometimes the unparenthesized walrus operator raises a syntax error. Also, don’t use walrus operators in seven scenarios to avoid confusion and ambiguity