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'?