Endlich ist er da. Der Walrus-Operator, eingeführt mit PEP 572 — Assignment Expressions.

Der Walrus-Operator ist mein persönliches Highlight, da ich ihn immer gebraucht habe – nur vorher wusste ich nicht wie sehr ich ihn gebraucht habe.

Er bringt eine riesen Erleichterung, macht unseren Code kompakter, lesbarer und natürlicher schöner (das Auge liest mit) 😬

PEP 572 beschreibt die Syntax des Walrus-Operators meiner Meinung nach perfekt:

In most contexts where arbitrary Python expressions can be used, a named expression can appear. This is of the form NAME := expr where expr is any valid Python expression other than an unparenthesized tuple, and NAME is an identifier.


The value of such a named expression is the same as the incorporated expression, with the additional side-effect that the target is assigned that value:


‒ PEP 572 # Syntax and semantics

Anwendungsbeispiele

Das Beispiel direkt aus dem PEP:

# Handle a matched regex
if (match := pattern.search(data)) is not None:
    # Do something with match

# A loop that can't be trivially rewritten using 2-arg iter()
while chunk := file.read(8192):
   process(chunk)

# Reuse a value that's expensive to compute
[y := f(x), y**2, y**3]

# Share a subexpression between a comprehension filter clause and its output
filtered_data = [y for x in data if (y := f(x)) is not None]

Ein schönes Beispiel von Victor Stinner (leicht angepasst):

># Without Walrus-Operator

while True:
    line = fp.readline()
    if not line:
        break
    match = pattern.search(line)

    if match:
        do_something_with_match(match)
    else:
        match = other_pattern.search(line)
        if match:
            do_something_with_match(match)
# With Walrus-Operator

while (line := fp.readline()):
    if (match := pattern.search(line)):
        do_something_with_match(match)
    elif (match := other_pattern.search(line)):
        do_something_with_match(match)

Aufwendige Berechnungen in List Comprehensions nicht wiederholen:

# Without Walrus-Operator

filtered_data = [
  complex_func(x) for x in data
  if complex_func(x) is not None
]

# With Walrus-Operator

filtered_data = [
  y for x in data
  if (y := complex_func(x)) is not None
]

Daten einer API erhalten:

# Without Walrus-Operator

import requests

book_information = requests.get(
    "https://openlibrary.org/api/books?bibkeys=ISBN:0201558025,LCCN:93005405&format=json"
)

for book_id in book_information.json():
    thumbnail_url = book_id['thumbnail_url']
    if thumbnail_url:
        print(f'Here is the thumbnail: {thumbnail_url}')
# With Walrus-Operator

import requests

book_information = requests.get(
    "https://openlibrary.org/api/books?bibkeys=ISBN:0201558025,LCCN:93005405&format=json"
)

for book_id in book_information.json():
    if (thumbnail_url := book_id['thumbnail_url']):
        print(f'Here is the thumbnail: {thumbnail_url}')