Skip to content

Commit 88adfd4

Browse files
authored
Merge branch 'master' into python-t-strings
2 parents 6d7495f + df05f8d commit 88adfd4

15 files changed

+277
-0
lines changed

python-namedtuple/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Write Pythonic and Clean Code With namedtuple
2+
3+
This folder provides the code examples for the Real Python tutorial [Write Pythonic and Clean Code With namedtuple](https://realpython.com/python-namedtuple/).

python-namedtuple/database.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
def get_column_names(table):
2+
if table == "passenger":
3+
return ("id", "first_name", "last_name", "class")
4+
raise ValueError(f"unknown table {table}")
5+
6+
7+
def get_passenger_by_id(passenger_id):
8+
if passenger_id == 1234:
9+
return (1234, "John", "Doe", "Business")
10+
raise ValueError(f"no record with id={passenger_id}")

python-namedtuple/employees.csv

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name,job,email
2+
"Linda","Technical Lead","[email protected]"
3+
"Joe","Senior Web Developer","[email protected]"
4+
"Lara","Project Manager","[email protected]"
5+
"David","Data Analyst","[email protected]"
6+
"Jane","Senior Python Developer","[email protected]"

python-namedtuple/employees.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import csv
2+
from collections import namedtuple
3+
4+
with open("employees.csv", mode="r", encoding="utf-8") as csv_file:
5+
reader = csv.reader(csv_file)
6+
Employee = namedtuple("Employee", next(reader), rename=True)
7+
for row in reader:
8+
employee = Employee(*row)
9+
print(employee)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from collections import namedtuple
2+
from dataclasses import dataclass
3+
4+
from pympler import asizeof
5+
6+
PointNamedTuple = namedtuple("PointNamedTuple", "x y z")
7+
8+
9+
@dataclass
10+
class PointDataClass:
11+
x: int
12+
y: int
13+
z: int
14+
15+
16+
namedtuple_memory = asizeof.asizeof(PointNamedTuple(x=1, y=2, z=3))
17+
dataclass_memory = asizeof.asizeof(PointDataClass(x=1, y=2, z=3))
18+
gain = 100 - namedtuple_memory / dataclass_memory * 100
19+
20+
print(f"namedtuple: {namedtuple_memory} bytes ({gain:.2f}% smaller)")
21+
print(f"data class: {dataclass_memory} bytes")
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from collections import namedtuple
2+
from dataclasses import dataclass
3+
from time import perf_counter
4+
5+
6+
def average_time(structure, test_func):
7+
time_measurements = []
8+
for _ in range(1_000_000):
9+
start = perf_counter()
10+
test_func(structure)
11+
end = perf_counter()
12+
time_measurements.append(end - start)
13+
return sum(time_measurements) / len(time_measurements) * int(1e9)
14+
15+
16+
def time_structure(structure):
17+
structure.x
18+
structure.y
19+
structure.z
20+
21+
22+
PointNamedTuple = namedtuple("PointNamedTuple", "x y z", defaults=[3])
23+
24+
25+
@dataclass
26+
class PointDataClass:
27+
x: int
28+
y: int
29+
z: int
30+
31+
32+
namedtuple_time = average_time(PointNamedTuple(x=1, y=2, z=3), time_structure)
33+
dataclass_time = average_time(PointDataClass(x=1, y=2, z=3), time_structure)
34+
35+
print(f"namedtuple: {namedtuple_time:.2f} ns")
36+
print(f"data class: {dataclass_time:.2f} ns")
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
from collections import namedtuple
2+
3+
from pympler import asizeof
4+
5+
Point = namedtuple("Point", "x y z")
6+
point = Point(1, 2, 3)
7+
8+
namedtuple_size = asizeof.asizeof(point)
9+
dict_size = asizeof.asizeof(point._asdict())
10+
gain = 100 - namedtuple_size / dict_size * 100
11+
12+
print(f"namedtuple: {namedtuple_size} bytes ({gain:.2f}% smaller)")
13+
print(f"dict: {dict_size} bytes")
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from collections import namedtuple
2+
from time import perf_counter
3+
4+
5+
def average_time(structure, test_func):
6+
time_measurements = []
7+
for _ in range(1_000_000):
8+
start = perf_counter()
9+
test_func(structure)
10+
end = perf_counter()
11+
time_measurements.append(end - start)
12+
return sum(time_measurements) / len(time_measurements) * int(1e9)
13+
14+
15+
def time_dict(dictionary):
16+
"x" in dictionary
17+
"missing_key" in dictionary
18+
2 in dictionary.values()
19+
"missing_value" in dictionary.values()
20+
dictionary["y"]
21+
22+
23+
def time_namedtuple(named_tuple):
24+
"x" in named_tuple._fields
25+
"missing_field" in named_tuple._fields
26+
2 in named_tuple
27+
"missing_value" in named_tuple
28+
named_tuple.y
29+
30+
31+
Point = namedtuple("Point", "x y z")
32+
point = Point(x=1, y=2, z=3)
33+
34+
namedtuple_time = average_time(point, time_namedtuple)
35+
dict_time = average_time(point._asdict(), time_dict)
36+
gain = dict_time / namedtuple_time
37+
38+
print(f"namedtuple: {namedtuple_time:.2f} ns ({gain:.2f}x faster)")
39+
print(f"dict: {dict_time:.2f} ns")

python-namedtuple/passenger.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from collections import namedtuple
2+
3+
from database import get_column_names
4+
5+
Passenger = namedtuple("Passenger", get_column_names("passenger"), rename=True)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from dataclasses import astuple, dataclass
2+
3+
4+
@dataclass
5+
class Person:
6+
name: str
7+
age: int
8+
height: float
9+
weight: float
10+
country: str = "Canada"
11+
12+
def __iter__(self):
13+
return iter(astuple(self))
14+
15+
16+
jane = Person("Jane", 25, 1.75, 67)
17+
for field in jane:
18+
print(field)

0 commit comments

Comments
 (0)