python-course.eu

5. Assignment Expressions

By Bernd Klein. Last modified: 30 Mar 2023.

Introduction

walrus

Python version 3.8 came with a new feauture, which some programmers of Python longed for for quite a while. A new way to assign objects to variables has been introduced, i.e. the := operator. It gives programmers a convenient way to assign variables in the middle of expressions. If you look at the characters with a little imagination you can see a similarity with the eyes and tusks of a walrus, so this is why affectionately known as the walrus operator.

The assignment expressions have been discussed in PEP 572 and this is what was written about the naming:

During discussion of this PEP, the operator became informally known as "the walrus operator". The construct's formal name is "Assignment Expressions" (as per the PEP title), but they may also be referred to as "Named Expressions" (e.g. the CPython reference implementation uses that name internally).

We will introduce this way of assignment in this part of our Python tutorial.

A simple assignment can also be replaced by an assignment expression, even though it looks clumsy and is definitely not the intended use case of it:

x = 5
# can be written as:
(x := 5)  # valid, but not recomended!
# the brackets are crucial

OUTPUT:

5

Let's look at a little Code example which only uses traditional assignments:

txt = 'Python needs training!'
ideal_length = 22

n = len(txt)
if n == ideal_length:
    print(f'The length {n} is ideal!')
else:
    print(f'{n} is not ideal!')

OUTPUT:

The length 22 is ideal!

We will use the new walrus operator in the following Python code snippet:

txt = 'Python needs training!'
ideal_length = 22

if (n := len(txt)) == ideal_length:
    print(f'The length {n} is ideal!')
else:
    print(f'The length {n} is not ideal!')

OUTPUT:

The length 22 is ideal!

Okay, you may say this is not very impressive and the first version might be considered as even more readable. So, let us have a look at a more useful usecase.

Live Python training

instructor-led training course

Enjoying this page? We offer live Python training courses covering the content of this site.

See: Live Python courses overview

Enrol here

Beneficial applications of the Assignment Expressions

List Comprehension

In the following you will see a list comprehension with a walrus operator:

def f(x):
    return x + 4

numbers = [3, 7, 2, 9, 12]

odd_numbers = [result for x in numbers if (result := f(x)) % 2]
odd_numbers

OUTPUT:

[7, 11, 13]

The above implementation is more efficient than a list comprehension without the assignment expression, because we will have to call the function twice:

def f(x):
    return x + 4

numbers = [3, 7, 2, 9, 12]

odd_numbers = [f(x) for x in numbers if  f(x) % 2]
odd_numbers

OUTPUT:

[7, 11, 13]

Regular Expressions

There is also a big advantage when we use regular expressions:

import re

txt = """The Python training course started at 2022-02-4 
the other one at 2022-01-24
only one date per line, if at all
the dates may also be in this format 2020/10/15
or 20-10-04"""

for line in txt.split('\n'):
    if (date := re.search(r'(\d{2,4})[-/](\d{2})[-/](\d{2})', line)):
        year, month, day = date.groups()
        print(year, month, day)

OUTPUT:

2022 01 24
2020 10 15
20 10 04

Reading Fixed Length Files

with open('training_course_info.txt') as fh:
    while ((data := fh.read(52)) != ''):
        print(data.rstrip())

OUTPUT:

Python Training Course for Beginners  Berlin     08
Python Intermediate Course            Hamburg    06
Python Advanced Trining Course        Frankfurt  08

Usage in while Loops

In the chapter on while loops of our Python Tutorial, we had a little number guessing game:

import random

lower_bound, upper_bound = 1, 20
to_be_guessed = random.randint(lower_bound, upper_bound)
guess = 0
while guess != to_be_guessed:
    guess = int(input("New number: "))
    if guess > to_be_guessed:
        print("Number too large")
    elif guess < to_be_guessed:
        print("Number too small")
else:
    print("Congratulations. You made it!")

As you can see, we had to initialize guess to zero to be able to enter the loop. We can do the initialization directly in the loop condition with an assignment expression and simplify the whole code by this:

import random

lower_bound, upper_bound = 1, 20
to_be_guessed = random.randint(lower_bound, upper_bound)

while (guess := int(input("New number: "))) != to_be_guessed:
    if guess > to_be_guessed:
        print("Number too large")
    elif guess < to_be_guessed:
        print("Number too small")
else:
    print("Congratulations. You made it!")

OUTPUT:

Number too small
Number too large
Number too small
Congratulations. You made it!

Taken to the extreme:

We said in the beginning of this page that some Python programmers longed for this consstruct for quite a while. One reason why it was not introduced earlier was the fact that it can also be used to write code which is less readable if used to extensivel. The following code snippet is showing such an extreme example which is not recommended to use:

a, b, c = 1, 2, 3
x = 4
y = (c := (a := x*2.3) + (b := x*4.5 -3)) 
y

OUTPUT:

24.2
c

OUTPUT:

24.2
a

OUTPUT:

9.2

Live Python training

instructor-led training course

Enjoying this page? We offer live Python training courses covering the content of this site.

See: Live Python courses overview

Upcoming online Courses

Enrol here