This is the third entry in a series covering PEPs in byte sized blog posts. Let us look at a PEP that has gained popularity in the past few months. PEP-572 which introduces named expressions in Python. It introduces a new way to assign names to expressions using a new operator :=, which has come to be known as the walrus operator. This is available from Python 3.8. Make sure to download the latest version of Python and give it a try.

If you do not understand what the following line does, then you should give this blog post a read.

[(x, x/2) for value in my_list if (x:=f(value)) > 0]

PS: The walrus operator can be misused in various ways and using it always does not improve the clarity of your code. Please be cautious in your usage.

PS: Hope it doesn’t become the interviewer’s favourite i++ ++i question. Anyone else hate those ?

Walrus operator in the if condition

Let us start with a simple if condition where you would want to return a non None value form a function. In the normal scenario,

x = foo(y)
if x:
  return x

The walrus operator can make this code more compact. It allows it to assign a name to the expression within the if function.

if x:=foo(y):
    return x

That is to say, assign the value of foo(y) to x and return the value if it is True. The statement is arguably clearer and saves writing an extra line.

Have you ever nested multiple if conditions like below ? It becomes hard to read such expressions over time.

y = foo(var_1)
if y:
  z = bar(var_2)
  if z:
    pass 
else:
  # do something else 

We had to write an extra line to store the value of the function evaluation before evaluating the expression.. Wouldn’t it be nice if we could store the value of the functions foo and bar within the if condition and use it if the value is true ? The Walrus operator reduces the complexity and helps you remove the nesting of if conditions.

if (y:= foo(var_1)) and (z:=bar(var_2)):
    print(y)
else:
  	# do something else 

What is more cool! You can use the result of one expression in the second part of the expression. Here is an example

## Old way 

diff = x - x_base 

if diff:
	g = gcd(diff, n)
	if g > 1:
    return g
  
## New way

if (diff:=x-x_base) and (g:= gcd(diff, n)) > 1:
  return g

If this blew your mind, stare at it for a couple of minutes and you will realise what just happened. Again, do not overuse the expression. If something is not clear, just split it into two statements and use it.

Walrus Operator in List Comprehension

List Comprehensions can make use of the walrus operator. Although this is less useful, you can store the intermediate value inside list comprehension and use it.

def foo(x):
	return log(x)

# old way 
[(i, foo(i), foo(i)**2) for i in range(0, 10, 0.1) if foo(i) > 0]

# new way
[(i, y, y**2) for i in range(0, 10, 0.1) if (y:= foo(i)) > 0]

You can avoid calling the foo() function twice using the naming expression. Storing intermediate values in complex expressions is one of the utilities of the walrus operator.

Conclusion

The walrus operator helps reduce the complexity of your code and makes it more readable. It is already being used by many developers to simplify python programming. I find it the most useful to reduce the complexity in the if condition.

Give the Walrus operator a try in your next programming project. If you have any other use-case for this operator that you have come across, do comment below. Until next time, cheers!