Professional Documents
Culture Documents
Python namedtuple
last modified July 6, 2020
Python namedtuple
Python namedtuple is an immutable container type, whose values can be accessed with indexes
and named attributes. It has functionality like tuples with additional features. A named tuple is
created with the collections.namedtuple factory function.
Named tuples are essentially easy-to-create, immutable, lightweight object types. Named tuples
can be used to make the code more clean and Pythonic. They are similar to records in other
languages (C#, Java).
basic.py
#!/usr/bin/env python3
c1 = City('Bratislava', 432000)
c2 = City('Budapest', 1759000)
print(c1)
print(c2)
We define the namedtuple. The first argument is the name for the namedtuple. The second
argument are the field names. These can be specified in a string 'name population' or in a list
['name', 'population'].
c1 = City('Bratislava', 432000)
c2 = City('Budapest', 1759000)
$ ./basic.py
City(name='Bratislava', population=432000)
City(name='Budapest', population=1759000)
accessing.py
#!/usr/bin/env python3
c1 = City('Bratislava', 432000)
c2 = City('Budapest', 1759000)
print(c1[0])
print(c1[1])
print(c2.name)
print(c2.population)
$ ./accessing.py
Bratislava
432000
Budapest
1759000
unpacking.py
#!/usr/bin/env python3
c1 = City('Bratislava', 432000)
c2 = City('Budapest', 1759000)
name, population = c1
print(f'{name}: {population}')
print('----------------------')
print(c2)
print(*c2, sep=': ')
name, population = c1
Here we unpack the c2 namedtuple with the * operator into print function arguments, which are
joined with the given separator into the final output.
$ ./unpacking.py
Bratislava: 432000
----------------------
City(name='Budapest', population=1759000)
Budapest: 1759000
c = City(**d)
print(c)
subclassing.py
#!/usr/bin/env python3
__slots__ = ()
@property
def hypot(self):
return sqrt((self.x ** 2 + self.y ** 2))
def __str__(self):
return f'Point: x={self.x} y={self.y} hypot={self.hypot}'
p = Point(5, 5)
print(p.hypot)
print(p)
$ ./subclassing.py
7.0710678118654755
Point: x=5 y=5 hypot=7.0710678118654755
Python typing.NamedTuple
Since Python 3.6, we can use the typing.NamedTuple to create a namedtuple.
named_tuple.py
#!/usr/bin/env python3
class City(NamedTuple):
name: str
population: int
c1 = City('Bratislava', 432000)
c2 = City('Budapest', 1759000)
print(c1)
print(c2)
In the example, we have a City class that inherits from the typing.NamedTuple. The attributes
have typehints.
defaults.py
#!/usr/bin/env python3
__slots__ = ()
@property
def hypot(self):
return sqrt((self.x ** 2 + self.y ** 2))
def __str__(self):
return f'Point: x={self.x} y={self.y} hypot={self.hypot}'
p1 = Point(5, 5)
print(p1)
p2 = Point()
print(p2)
$ ./defaults.py
Point: x=5 y=5 hypot=7.0710678118654755
Point: x=1 y=1 hypot=1.4142135623730951
helpers.py
#!/usr/bin/env python3
class Point(NamedTuple):
x: int = 1
y: int = 1
p = Point(5, 5)
print(p._fields)
print(p._field_defaults)
print(p._asdict())
The _fields is a tuple of strings listing the field names. The _field_defaults is a dictionary
mapping field names to default values. The _asdict method returns a new ordered dictionary,
which maps field names to their corresponding values.
$ ./helpers.py
('x', 'y')
{'x': 1, 'y': 1}
OrderedDict([('x', 5), ('y', 5)])
json_output.py
#!/usr/bin/env python3
class City(NamedTuple):
name: str
population: int
c1 = City('Bratislava', 432000)
c2 = City('Budapest', 1759000)
c3 = City('Prague', 1280000)
c4 = City('Warsaw', 1748000)
print(json.dumps(c1._asdict()))
With the help of the json.dumps method, we serialize a single city and a list of cities.
$ ./json_output.py
{"name": "Bratislava", "population": 432000}
[{"name": "Bratislava", "population": 432000}, {"name": "Budapest", "population": 1759000},
{"name": "Prague", "population": 1280000}, {"name": "Warsaw", "population": 1748000}]
sorting.py
#!/usr/bin/env python3
class City(NamedTuple):
id: int
name: str
population: int
cities.sort(key=lambda e: e.name)
With the help of the sort method and the lambda function, we sort cities by their name.
$ ./sorting.py
City(id=7, name='Berlin', population=3671000)
City(id=1, name='Bratislava', population=432000)
City(id=2, name='Budapest', population=1759000)
City(id=6, name='Edinburgh', population=464000)
City(id=5, name='Los Angeles', population=3971000)
City(id=3, name='Prague', population=1280000)
City(id=4, name='Warsaw', population=1748000)
making.py
#!/usr/bin/env python3
print(c1)
print(c2)
The example creates City namedtuples from tuples with the help of the _make method.
cities.csv
Bratislava, 432000
Budapest, 1759000
Prague, 1280000
Warsaw, 1748000
Los Angeles, 3971000
New York, 8550000
Edinburgh, 464000
Berlin, 3671000
read_csv.py
#!/usr/bin/env python3
f = open('cities.csv', 'r')
with f:
reader = csv.reader(f)
We use the map and the _make functions to create clean code.
$ ./read_csv.py
City(name='Bratislava', population=' 432000')
City(name='Budapest', population=' 1759000')
City(name='Prague', population=' 1280000')
City(name='Warsaw', population=' 1748000')
City(name='Los Angeles', population=' 3971000')
City(name='New York', population=' 8550000')
City(name='Edinburgh', population=' 464000')
City(name='Berlin', population=' 3671000')
$ sqlite3 ydb.db
SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints.
sqlite> .read cities.sql
With the sqlite3 command line tool, we generate the SQLite database and the cities table.
read_sql.py
#!/usr/bin/env python3
class City(NamedTuple):
id: int
name: str
population: int
con = sqlite.connect('ydb.db')
with con:
cur = con.cursor()
We read all data from the cities table and transform each table row into a City namedtuple.