[ Web Proxy ]
URL:
Viewing: https://python-course.eu/python-tutorial/assignment-expressions.php [Back]  [Original]

5. Assignment Expressions | Python Tutorial | python-course.eu
python-course.eu
Search site:

Live Python classes by highly experienced instructors:

instructor-led training course [instructor-led training course]
Instructor-led training courses by Bernd Klein

  1. Intro to Python Tutorial
  2. History and Philosophy of Python
  3. The Interpreter, an Interactive Shell
  4. Execute a Script
  5. Structuring with Indentation
  6. Assignment Expressions
  7. Data Types and Variables
  8. Type Annotations
  9. Operators
  10. Sequential Data Types
  11. List Manipulation
  12. Shallow and Deep Copy
  13. Dictionaries
  14. Sets and Frozen Sets
  15. Sets Examples
  16. Keyboard Input
  17. Conditional Statements
  18. Structural Pattern Matching
  19. Adventure Game with Structural Pattern Matching
  20. While Loops
  21. For Loops
  22. Output with Print
  23. Formatted Output
  24. Working with Dictionaries and while Loops
  25. Functions
  26. Passing Arguments
  27. Parameters And Arguments
  28. Namespaces
  29. Global vs. Local Variables and Namespaces
  30. File Management
  31. Modular Programming and Modules
  32. Packages
  33. Errors and Exception Handling

This website contains a free and extensive online tutorial by Bernd Klein, using material from his classroom Python training courses.

If you are interested in an instructor-led classroom training course, have a look at these Python classes:

instructor-led training course [instructor-led training course]
Instructor-led training course by Bernd Klein at Bodenseo

Image kabliczech - Fotolia.com

This page was written by Bernd Klein.

Bernd is an experienced computer scientist with a history of working in the education management industry and is skilled in Python, Perl, Computer Science, and C++. He has a Dipl.-Informatiker / Master Degree focused in Computer Science from Saarland University.

PDF versions of this site [PDF versions of this site]

PDF logo [PDF logo] PDF version of this site

This website is free of annoying ads. We want to keep it like this. You can help with your donation:

[Go]

The need for donations

5. Assignment Expressions

By Bernd Klein. Last modified: 30 Nov 2023.

Introduction

walrus [walrus]

This section in our Python tutorial explores the "assignment expression operator" affectionately known to many as "the walrus operator. So, you can call it either the "walrus operator" or the "assignment expression operator," and people in the Python programming community will generally understand what you mean. Despite being introduced in Python version 3.8, we can still view it as a relatively recent addition to the language. 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).

The purpose of this feature is not a new way to assign objects to variables, but it gives programmers a convenient way to assign variables in the middle of expressions.

You might still be curious about the origin of the term "walrus operator." It's affectionately named this way because, with a touch of imagination, the operator's characters resemble the eyes and tusks of a walrus.

We will introduce the assignment expression by comparing it first with a simple assignment statement. A simple assignment statement 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

First you may wonder about the brackets, when you look at the assignment expression. It is not meant as a replacement for the simple "assignment statement". Its primary role is to be utilized within expressions

The following code shows a proper usecase:

x = 4.56
z = (square := x**2) - (6.6 / square)
print(z)

OUTPUT:

20.476194644506

Though you may argue that the following code might be even clearer:

x = 4.56
square = x**2
z = square - (6.6 / square)
print(z)

OUTPUT:

20.476194644506

Here's another Python code example that demonstrates a similar scenario. First with the walrus operator:

# With the walrus operator
n = int(input("Please give a number: "))
if (square := n ** 2) > 3:
    print("The number is greater than 3.")
    print(f"The square of {n} is {square}.")

OUTPUT:

The number is greater than 3.
The square of 42 is 1764.

Now without the walrus operator:

n = int(input("Please give a number: "))
square= n ** 2
if square > 3:
    print("The number is greater than 3.")
    print(f"The square of {n} is {square}.")

OUTPUT:

The number is greater than 3.
The square of 42 is 1764.

Live Python training

instructor-led training course [instructor-led training course]

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

See our Python training courses

See our Machine Learning with Python training courses

Beneficial applications

Now, let's explore some examples where the usage of the assignment expression is really beneficial compared to code not using it.

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]

You can observe that if we choose to avoid using the assignment expression in the list comprehension, we would need to call the function twice. So using the assgment expression makes the code in this context more efficient.

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]

Use Case: Regular Expressions

There is also a great advantage when we use regular expressions. Like in our previous examples we present again two similiar code snippets, the first one without and the second one with the walrus operator:

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'):
    date = re.search(r'(\d{2,4})[-/](\d{2})[-/](\d{2})', line)
    if date:
        year, month, day = date.groups()
        print(f"Found date: {year}-{month}-{day}")

OUTPUT:

Found date: 2022-01-24
Found date: 2020-10-15
Found date: 20-10-04

Now, the code using assignment 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"""

# Split the text into lines and search for dates in each line
for line in txt.split('\n'):
    # Using the assignment expression to find and store the date match
    if (date := re.search(r'(\d{2,4})[-/](\d{2})[-/](\d{2})', line)):
        year, month, day = date.groups()
        print(f"Found date: {year}-{month}-{day}")

OUTPUT:

Found date: 2022-01-24
Found date: 2020-10-15
Found date: 20-10-04

Assignment Expression in File Reading

Fixed-width Files

Files in which each line has the same length are often referred to as "fixed-width" or "fixed-length" files. In these files, each line (or record) is structured so that it contains a predefined number of characters, and the fields within the lines have fixed positions. The files can be read by using the read-method and the walrus operator:

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

OUTPUT:

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

Now the same in traditional coding style:

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

OUTPUT:

Python Training Course for Beginners   Berlin     08

Python Intermediate Course             Hamburg    0
6
Python Advanced Training Course        Frankfurt
08

The benefits for the most recent code snippet are

However, a significant drawback of this approach is that it requires the explicit assignment and reassignment of the data variable, which can be seen as less concise and somewhat less elegant.

Using readline

Most people use a for loop to iterator over a text file line by line. With the walrus operator, we can also elegantly go through a text using the method readline:

word_to_find = "Advanced"
with open("training_course_info.txt") as file:
    while (line := file.readline()):
        if word_to_find in line:
            print(line)

OUTPUT:

Python Advanced Training Course        Frankfurt  08

Code snippet using readline but not the assignment expression:

word_to_find = "Advanced"
with open("training_course_info.txt") as file:
    line = "It shouldn't be empyt that's all"
    while line:
        line = file.readline()
        if word_to_find in line:
            print(line)

OUTPUT:

Python Advanced Training Course        Frankfurt  08

Now with the walrus operator:

word_to_find = "Training"
with open("training_course_info.txt") as file:
    while (line := file.readline()):
        if word_to_find in line:
            print(line)

OUTPUT:

Python Training Course for Beginners   Berlin     08

Python Advanced Training Course        Frankfurt  08

Another Use Case

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!")

OUTPUT:

Number too small
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
Congratulations. You made it!

Critiques of the Walrus Operator in Python

the Python walrus [the Python walrus]

We said in the beginning of this page that some Python programmers longed for this construct 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. In fact, the application of the walrus operator contradicts several principles highlighted in the Zen of Python. To grasp these contraventions, let's delve into the ensuing scenarios.

The Zen of Python says "Explicit is better than implicit". The walrus operator violates this requirement of the Zen of Python. This means that explicit operations are always better than implicit operations. The walrus operator assigns a value to a variable and implicitly returns the value as well. Therefore, it does not align with the concept of "Explicit is better than implicit."

The following code snippet is shows 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)) 

What are your thoughts on the following piece of code using the Python assignment operator inside of a print function call?

print((a := x*2.3) + (b := x*4.5 -3) + (x := 4))

OUTPUT:

28.2

These Python code snipets certainly violate two other demands of the Zen of Python:

  1. Beautiful is Better Than Ugly
  2. Complex is Better Than Complicated

The principle "There should be one and preferably only one obvious way to do it" from the Zen of Python emphasizes the importance of having a clear and singular approach. When we have the option to separate assignment and return operations into distinct statements, opting for the less readable and more complex walrus operator contradicts this principle.

z = (x:=3) + (y:=4)
This is the preferred way to do it
x, y = 3, 4
z = x + y

Live Python training

instructor-led training course [instructor-led training course]

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

Upcoming online Courses

See our Python training courses

See our Machine Learning with Python training courses

top


Web Proxy Viewer  |  New URL  |  Original Page