AI Hints
Home›Python Tutorial›Modern Python and Clean Code
Python · Lesson 44 of 49

Modern Python Features

Match, walrus and more.

⏱ 2 min read▶ Video at 2:12:48🎓 Free
Watch this lesson in the Python courseWatch on YouTube ↗Full Python course

Python keeps getting better, and newer versions add features that make code shorter, and clearer. Ava wants to write modern code. In this lesson, you will meet structural pattern matching, the walrus operator, richer unpacking, and a few small, but delightful improvements, that you will use every week.

Modern Python Features
From the video: Modern Python Features
  • Python keeps improving
  • Shorter, clearer code
  • Features you will use weekly

match and case

The match statement compares a value against patterns. Each case can match a literal, a shape, like a list of two items, or a dictionary, and even bind variables, in one step. It is far more than a switch. Here, Ava's shop handles different kinds of commands, with one tidy block.

match1.pypython
def handle(cmd):
    match cmd:
        case ["add", name]:
            return f"adding {name}"
        case ["add", name, qty]:
            return f"adding {qty} x {name}"
        case {"remove": name}:
            return f"removing {name}"
        case "help" | "?":
            return "commands: add, remove"
        case _:
            return "unknown"

print(handle(["add", "fern"]))
print(handle(["add", "ivy", 3]))
print(handle({"remove": "rose"}))
print(handle("?"))
print(handle(42))
Output
adding fern
adding 3 x ivy
removing rose
commands: add, remove
unknown

The walrus operator

The walrus operator, a colon followed by an equals sign, assigns a value, inside an expression. It avoids calling something twice. In a while loop, it reads and tests in one line. In a comprehension, it computes a value once, and uses it twice. Use it where it makes code shorter, and still clear.

walrus.pypython
data = ["fern", "", "ivy", "rose"]
for s in data:
    if (n := len(s)) > 3:
        print(s, "is long:", n)

prices = [9.5, 24.0, 7.0]
with_tax = [t for p in prices if (t := p * 1.2) > 10]
print(with_tax)
Output
fern is long: 4
rose is long: 4
[11.4, 28.799999999999997]

Better unpacking

Star unpacking captures the rest of a sequence. The first item, a middle list, and the last item, in one line. You can merge lists and dictionaries with stars, and the pipe operator merges dictionaries. And keyword only arguments, after a star, force clearer calls, while a slash makes parameters positional only.

unpack.pypython
first, *middle, last = [1, 2, 3, 4, 5]
print(first, middle, last)
a, b = [1, 2], [3]
print([*a, *b, 99])
d1, d2 = {"x": 1}, {"y": 2}
print({**d1, **d2}, d1 | d2)

def order(item, /, qty=1, *, gift=False):
    return item, qty, gift

print(order("fern", 2, gift=True))
Output
1 [2, 3, 4] 5
[1, 2, 3, 99]
{'x': 1, 'y': 2} {'x': 1, 'y': 2}
('fern', 2, True)

Small modern touches

A few more. F strings can show a debug value, with an equals sign, and format numbers with underscores or commas. The pathlib module replaces os path. Dictionary and set operators are neat. And zip has a strict option, that raises an error when lists differ in length. Together these make everyday code a pleasure.

touches.pypython
x = 1234567.891
print(f"{x:,.2f}")
print(f"{x=:.1f}")
print(1_000_000 + 1)
names, ages = ["a", "b"], [1]
try:
    list(zip(names, ages, strict=True))
except ValueError as e:
    print("lengths differ")
print(max([], default=0))
Output
1,234,567.89
x=1234567.9
1000001
lengths differ
0

Match a shape

Your turn. Use a match statement, with a function that takes a point as a tuple. For zero, zero, return origin. For a tuple with x and zero, return on the x axis. For anything else, return elsewhere. Ready? Here is one solution. Three cases, with a variable pattern.

✍️ Exercise: Match a shape

Write where(p): (0, 0) -> "origin", (x, 0) -> "x axis", anything else -> "elsewhere".

Show hint

case (x, 0):

Show solution
where.pypython
def where(p):
    match p:
        case (0, 0):
            return "origin"
        case (x, 0):
            return "x axis"
        case _:
            return "elsewhere"

print(where((0, 0)), where((5, 0)), where((1, 2)))
Output
origin x axis elsewhere

Summary

Great progress. You can match patterns, use the walrus operator, unpack with stars, and enjoy several small modern improvements. Next, we talk about the habits that separate good code from great, clean code, and design patterns.

Key takeaways
  • match / case for structured data
  • walrus := assigns inside expressions
  • Star unpacking, | for dict merging
Next up: Clean Code and Design Patterns — habits of top Python developers