2.10. New Features in Python#

This section shows some new features in Python 3.10 and above.

2.10.1. Python Switch Statement#

It is common to use the if-else statements to execute multiple conditional statements.

def get_price(food: str):
    if food == "apple":
        return 4
    elif food == "orange":
        return 3
    elif food == "grape":
        return 5
    else:
        return "Unknown"


get_price("apple")
4

In Python 3.10 and above, you can use the switch statement to do the same thing.

With the switch statement, you don’t need to repeat the same statements multiple times (food==x), which makes the code cleaner than using multiple if-else statements.

def get_price(food: str):
    match food:
        case "apple": # if food == "apple"
            return 4
        case "orange":
            return 3
        case "grape":
            return 5
        case _:        # else
            return "Unknown"

get_price("apple")
4

2.10.2. Structural Pattern Matching in Python 3.10#

Have you ever wanted to match complex data types and extract their information?

Python 3.10 allows you to do exactly that with the match statement and the case statements.

The code below uses structural pattern matching to extract ages from the matching data structure.

def get_youngest_pet(pet_info):
    match pet_info:
        case [{"age": age1}, {"age": age2}]:
            print("Age is extracted from a list")
            return min(age1, age2)

        case {'age': {}}:
            print("Age is extracted from a dict")
            ages = pet_info['age'].values()
            return min(ages)
pet_info1 = [{"name": "bim", "age": 1}, {"name": "pepper", "age": 9}]
get_youngest_pet(pet_info1)
Age is extracted from a list
1
pet_info2 = {'age': {"bim": 1, "pepper": 9}}
get_youngest_pet(pet_info2)
Age is extracted from a dict
1

2.10.3. Write Union Types as X|Y in Python 3.10#

Before Python 3.10, you need to use typing.Union to declare that a variable can have one of several different types.

from typing import Union

num = 2.3
isinstance(num, Union[int, float])
True

In Python 3.10, you can replace Union[X, Y] with X | Y to simplify the expression.

isinstance(num, int | float)
True

2.10.4. Walrus Operator: Assign a Variable in an Expression#

The walrus operator (:=) in Python 3.8 and above allows you to assign a variable in an expression. The walrus operator is useful when you want to:

  • Debug the components in an expression

  • Avoid repeated computations

  • Assign a meaningful name to an expression

from math import pi

diameter = 4
# without Walrus operator

circle = {
    "radius": diameter / 2, # computed twice
    "area": pi * (diameter / 2)**2,
}

diameter / 2
2.0
# with Walrus operator

circle = {
    "radius": (radius := diameter / 2),
    "area": pi * radius**2,
}

radius
2.0

2.10.5. Fine-Grained Traceback in Python 3.11#

Having a clear traceback makes it faster to debug your code. Python 3.11 provides fine-grained error locations in tracebacks, enabling developers to quickly identify the exact location of errors.

The following examples illustrate the difference in traceback between Python 3.9 and Python 3.11.

%%writefile trackback_test.py
def greet(name):
    greeting = "Hello, " + name + "!"
    print(greetng) # Error: Typo in variable name

greet("Khuyen")
# Python 3.9
$ python trackback_test.py
Traceback (most recent call last):
  File "/Users/khuyentran/book/Efficient_Python_tricks_and_tools_for_data_scientists/Chapter1/trackback_test.py", line 5, in <module>
    greet("Khuyen")
  File "/Users/khuyentran/book/Efficient_Python_tricks_and_tools_for_data_scientists/Chapter1/trackback_test.py", line 3, in greet
    print(greetng) # Error: Typo in variable name
NameError: name 'greetng' is not defined
# Python 3.11
$ python trackback_test.py
Traceback (most recent call last):
  File "/Users/khuyentran/book/Efficient_Python_tricks_and_tools_for_data_scientists/Chapter1/trackback_test.py", line 5, in <module>
    greet("Khuyen")
  File "/Users/khuyentran/book/Efficient_Python_tricks_and_tools_for_data_scientists/Chapter1/trackback_test.py", line 3, in greet
    print(greetng) # Error: Typo in variable name
          ^^^^^^^
NameError: name 'greetng' is not defined. Did you mean: 'greeting'?