Walrus and the Python | Introduction to Walrus Operator
Python 3.8 brought in several new features to the language like the positional only arguments, debug f-strings, improved type checking, etc, but none was as talked about as the Walrus operator.
Why the name?
The operator is :=
. It looks like the eyes and tusks of a walrus. Hence the affectionate name, “walrus operator”.
What is the Walrus Operator?
Walrus operator is a new way to perform assignment in Python 3.8, introduced to prevent code duplication. (PEP-572)
How to use it?
Let’s see how we can use Walrus operator with five examples.
If Conditions
Take an example code as follows where we are printing if the length of the list is more than an expected value.
numbers = [1, 2, 3, 4, 5]
if len(numbers) >= 4:
print(f'List is too long. Has {len(numbers)} elements')
Here we are calculating the length twice with len(numbers)
. This can slow the code if the list is very long. This is where the Walrus operator comes in. We can be simplify this with walrus operator as follows:
numbers = [1, 2, 3, 4, 5]
if (length := len(numbers)) >= 4:
print(f'List is too long. Has {length} elements')
The len(numbers)
is calculated once and stored in the length
variable with the assignment expression length := len(numbers)
. This eliminates the double calculation and still keeps the code length the same.
Note the brackets around the walrus expression in (length := len(numbers)) >= 4
. This is needed because the Walrus operator has lower precedence than the >=
operator. Without the brackets, the expression would have been evaluated as length := (len(numbers) >=4)
, which would put a True
in length
instead of 4
.
List Comprehension
We can use Walrus operator in List comprehension as well to eliminate computational redundancy.
Say, we have a piece as follows where we are printing the even squares of numbers.
numbers = [1, 2, 3, 4, 5]
even_squares = [n * n for n in numbers if n * n % 2 == 0]
print(even_squares) # [4, 16]
Again here, we are doing the computation of n*n
twice. Walrus to the rescue. That above code can be rewritten with :=
as follows:
numbers = [1, 2, 3, 4, 5]
even_squares = [s for n in numbers if (s := n * n) % 2 == 0]
print(even_squares) # [4, 16]
The n*n
is computed once and stored in s
with s := n*n
and that s
is returned from the list comprehension without having to recompute it.
Calling Functions
The next example is for the case where you are using the value from a function in multiple places.
Say, you have a piece as follows:
def get_value_from_db():
return 10
x = get_value_from_db()
y = [x // 2, x, x * 2]
print(y)# [5, 10, 20]
The list y
gets populated using x
. The above code is completely fine on its own but we can choose to rewrite it with walrus operator as follows:
y = [(x := get_value_from_db()) // 2, x, x * 2]
print(y) # [5, 10, 20]
Instead of calculating the x
value outside, we can compute it in the list itself and use it, making the code shorter by a line!
While Loops
Walrus operator can be used with while loops as well, especially with infinite loops.
Here, we have a password guessing game, where the code loops until the user enters the correct password.
while True:
user_input := input('What is the secret word? ')
if user_input == 'swordfish':
break
print(f'You have entered {user_input}. Try again..')
That code can be made much shorter by using Walrus operator as follows:
while (user_input := input('What is the secret word? ')) != 'swordfish':
print(f'You have entered {user_input}. Try again..')
In just two lines, we were able to capture the same functionality as before.
For Loops
For the final example, we look at how we can use Walrus operator with in a for-loop.
Say, we have a list of people as follows:
people = [
{'name': 'Adam', 'age': 25},
{'name': 'Adriana', 'age': 30},
{'name': '', 'age': 28},
]
Each element in the list is a dictionary with the keys name
and age
.
We would iterate over that list as follows, printing each name if it exists.
for person in people:
if person['name']:
print(f'We have {person["name"]}')
This can also ‘simplified’ with the :=
operator.
for person in people:
if name := person['name']:
print(f'We have {name}')
Of Course, this is not really doing much as the lookup on dictionary is already fast enough but you could do something like that if you choose.
Those are five different ways in which you can use the Walrus operator.
Word Of Caution
The introduction of Walrus operator in Python was quite controversial and is infact one of the main reasons for Guido Von Rossum (creator of Python) to step down from his role as BDFL. A lot of people thought it would obscure the readability of the Python language. This is possible, if the programmer is not careful about where they use Walrus operator.
As long as you use it responsibly and sparingly, Walrus operator has its place in the language providing a new syntactical outlet for your thoughts.
I have made a youtube video about this topic. Do check it out for some more details about the Walrus operator along with the above examples:
Thank you for reading this article. Here are some other articles you might like:
Attribution
Documentation references from https://docs.python.org/3/whatsnew/3.8.html
Walrus Image — Public Domain — https://commons.wikimedia.org/wiki/File:Pacific_Walrus_-_Bull_(8247646168).jpg