Python namedtuple

Filed Under: Python

Python namedtuple object is part of collections module. Python namedtuple is an extension of tuple.

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 the defaults 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.

You can checkout complete python script and more Python examples from our GitHub Repository.

Reference: API Doc

Leave a Reply

Your email address will not be published. Required fields are marked *

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages