Python namedtuple object is part of collections module. Python namedtuple is an extension of tuple.
Table of Contents
Python namedtuple
- Python namedtuple is immutable just like tuple.
- Namedtuple allows us to provide names to the elements. So we can access elements both by index value or by name.
- Python namedtuple helps us in writing better readable code. If the tuple has many values, using index becomes confusing. With namedtuple, we can provide descriptive names to the fields.
- Python namedtuple field names can be any valid Python identifier. Valid identifiers consist of letters, digits, and underscores but do not start with a underscore or digit. Also, we cannot use keywords such as class, for, def, return, global, pass, or raise etc.
- We can specify default values to the namedtuple parameters using
defaults
parameter while defining the namedtuple. Note that this feature has been added in Python 3.7. - Python namedtuple instances do not have per-instance dictionaries, so they are lightweight and require no more memory than regular tuples.
Quick Revisit to Tuple
Before we start with namedtuple examples, let’s have a quick look on python tuple. We will create a few tuples and print their values to console.
emp1 = ('Pankaj', 35, 'Editor')
emp2 = ('David', 40, 'Author')
for p in [emp1, emp2]:
print(p)
for p in [emp1, emp2]:
print(p[0], 'is a', p[1], 'years old working as', p[2])
# pythonic way
for p in [emp1, emp2]:
print('%s is a %d years old working as %s' % p)
Output:
('Pankaj', 35, 'Editor')
('David', 40, 'Author')
Pankaj is a 35 years old working as Editor
David is a 40 years old working as Author
Pankaj is a 35 years old working as Editor
David is a 40 years old working as Author
Notice that we are using indexes to retrieve tuple elements.
Python namedtuple example
Python namedtuple is created using factory method from the collections module. This functions signature is as follows:
collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)
typename
: This is the name of the namedtuple object.field_names
: This is the second argument to define the field names in the namedtuple. We can define them using following formats –'name age role'
,'name,age,role'
, or['name', 'age', 'role']
.rename
: We can specify rename to True so that invalid fields are renamed to their index names. For example,'name def class'
will be renamed to'name', '_1', '_2'
.defaults
: It’s used to define default values to the optional parameters. Since fields with a default value must come after any fields without a default, the defaults are applied to the rightmost parameters. For example, if the fieldnames are['a', 'b', 'c']
and thedefaults
are (1, 2), then ‘a’ will be a required argument, ‘b’ will default to 1, and ‘c’ will default to 2.module
: If module is defined, the__module__
attribute of the named tuple is set to that value. This parameter was introduced in Python 3.6 release.
Let’s see a simple example to create namedtuple and print its values.
from collections import namedtuple
Employee = namedtuple('Employee', ['name', 'age', 'role'])
# below are also valid ways to namedtuple
# Employee = namedtuple('Employee', 'name age role')
# Employee = namedtuple('Employee', 'name,age,role')
emp1 = Employee('Pankaj', 35, 'Editor')
emp2 = Employee(name='David', age=40, role='Author')
for p in [emp1, emp2]:
print(p)
# accessing via index value
for p in [emp1, emp2]:
print('%s is a %d years old working as %s' % p)
# accessing via name of the field
for p in [emp1, emp2]:
print(p.name, 'is a', p.age, 'years old working as', p.role)
Notice that I am using namedtuple field names to retrieve the values. More or less it’s almost the same as earlier tuple example program.
Output:
Employee(name='Pankaj', age=35, role='Editor')
Employee(name='David', age=40, role='Author')
Pankaj is a 35 years old working as Editor
David is a 40 years old working as Author
Pankaj is a 35 years old working as Editor
David is a 40 years old working as Author
Python namedtuple with invalid keys and rename
If we use invalid keys for namedtuple names, then we will get ValueError
.
try:
Person = namedtuple('Person', 'def class')
except ValueError as error:
print(error)
Output:
Type names and field names cannot be a keyword: 'def'
Now let’s see what happens when we specify rename as True.
# rename=True will rename invalid names to index value with underscore prefix
Person = namedtuple('Person', 'name def class', rename=True)
print(Person._fields)
Output:
('name', '_1', '_2')
Notice that field names are changed to their index values prefixed with an underscore.
Python namedtuple module
# namedtuple module parameter - introduced in 3.6
Person = namedtuple('Person', 'name', module='MyPersonModule')
print(Person.__module__)
Output:
MyPersonModule
Python namedtuple additional methods
Let’s look at three additional methods available for namedtuple.
_make(iterable)
This classmethod can be used to create namedtuple from an iterable.
t = ('Lisa', 35, 'Contributor')
emp3 = Employee._make(t)
print(emp3)
Output:
Employee(name='Lisa', age=35, role='Contributor')
_asdict()
This is used to create an OrderedDict instance from a namedtuple.
od = emp3._asdict()
print(od)
Output:
OrderedDict([('name', 'Lisa'), ('age', 35), ('role', 'Contributor')])
_replace(**kwargs)
Python namedtuple is immutable, so we can’t change its values. This method returns a new instance of namedtuple replacing specified fields with new values.
emp3 = emp3._replace(name='Lisa Tamaki', age=40)
print(emp3)
Output:
Employee(name='Lisa Tamaki', age=40, role='Contributor')
Python namedtuple additional attributes
There are two additional parameters in namedtuple – _fields and _fields_defaults. As the name suggests, they provide information about the fields and their default values. Python 3.7 dropped _source attribute.
print(emp3._fields)
Gender = namedtuple('Gender', 'gender')
Person = namedtuple('Person', Employee._fields + Gender._fields)
print(Person._fields)
# _fields_defaults - introduced in Python 3.7
# Python 3.7 removed verbose parameter and _source attribute
Person1 = namedtuple('Person1', ['name', 'age'], defaults=['Pankaj', 20])
print(Person1._fields_defaults)
Output:
('name', 'age', 'role')
('name', 'age', 'role', 'gender')
{'name': 'Pankaj', 'age': 20}
Python namedtuple miscellaneous examples
Let’s look at some miscellaneous examples of namedtuple.
getattr()
We can get the namedtuple field value using getattr() function too.
emp3_name = getattr(emp3, 'name')
print(emp3_name)
Output:
Lisa Tamaki
Dict to Named Tuple
Named tuple and Dict are very similar, so it’s no wonder that there is a quick way to convert dict to namedtuple.
d = {'age': 10, 'name': 'pankaj', 'role':'CEO'}
emp4 = Employee(**d)
print(d)
print(emp4)
Output:
{'age': 10, 'name': 'pankaj', 'role': 'CEO'}
Employee(name='pankaj', age=10, role='CEO')
Summary
Python namedtuple is useful in writing better code with more readability. It’s very lightweight just like tuple, so use it when you find tuples are confusing because of using numeric indexes.
Reference: API Doc