The Python collections
module provides a helpful factory function, namedtuple
, which allows you to create named tuples in Python. The idea behind named tuples is to make working with tuples more pythonic by allowing you to access data in the tuple using their label, rather than their index position.
The named tuple extends the Python tuple. This means that it can do everything a normal tuple can, but it adds helpful features. Namely, it allows you to provide create objects with named fields and a fixed length.
By the end of this tutorial, you’ll have learned:
- How to create a
namedtuple
object using thecollections
library - Understand how the named tuple is different from a regular tuple
- When you may want to use a named tuple over a regular tuple or a Python dictionary
- Understand how to use the named tuple’s powerful methods and arguments
Table of Contents
What is a Python named tuple
The namedtuple()
function available in the Python collections
module is a factory function to generate special tuples. In particular, these tuples are a subclass of normal Python tuples, but allow you to use named fields in their values. Similar to accessing an object’s attribute, you can use dot notation to access a named value in a named tuple.
Python named tuples make your code cleaner to read since it allows you to access a value in a tuple without referencing its index. Say you wanted to have a tuple that stores a person’s name, age, location, and profession. In a named tuple, you could access the person’s profession by accessing that attribute.
# Accessing an attriute
named_tuple.attribute_name
To better explain why this is better, let’s take a look at a regular tuple. Our tuple will contain someone’s name, age, location, and profession.
# Creating a regular tuple
nik_tuple = ('Nik', 33, 'Toronto', 'datagy')
In order to access the profession, you need to know where in that tuple the information is stored. While this seems like an easy task, it does add an additional layer of interpretation to your reader.
In this example, you’d need to access either the index of 3 (or of -1):
print(nik_tuple[3])
# Returns: datagy
On the other hand, we can recreate this tuple used a namedtuple
. In the case of a named tuple, you won’t need to know the index position – only its label. In the next section, you’ll learn how to create a named tuple.
Creating a Python Named Tuple Using Collections
In this section, you’ll learn how to create a namedtuple
using the Python collections
module. Let’s see what the namedtuple()
function looks like:
# Understanding the namedtuple() Function
from collections import namedtuple
namedtuple(
typename, # The type name to be used for the tuple
field_names, # The field names to be used
rename=False, # Whether to automatically rename reserved names
defaults=None, # Whether to include default values
module=None # Whether to assign a custom module value
)
Let’s break down the arguments available in the namedtuple()
function:
Parameter | Description | Notes |
---|---|---|
typename= | The class name to be used for the named tuple | Must be a string |
field_names= | The field names to be used in the tuple | Can be any of the following: 1. A list of strings ( ['a', 'b', 'c'] )2. A string separated by spaces ( 'a b c' )3. A string separated by commas ( 'a, b, c' ) |
rename= | Whether to automatically rename fields that are not allowed | Prepends an underscore to any field names that are not allowed (e.g., reserved or duplicate) |
defaults= | Default values to assign to a field names. | Values are assigned to the right-most field names. For example, a 3 field name namedtuple that is provided 2 defaults, will have its first fieldname be required. |
module= | The value to use for a custom module, if applicable. | Allows you to pass in information in whcih module the namedtuple is defined. |
Now that you have an understanding of the parameters available in the namedtuple()
function, let’s see how you can recreate the tuple from above.
# Creating your first namedtuple
from collections import namedtuple
Person = namedtuple('Person', ['name', 'age', 'location', 'profession'])
nik = Person('nik', 33, 'Toronto', 'datagy')
print(nik.profession)
# Returns: datagy
Similarly, named tuples can also be indexed. For example, you could access the profession value by accessing its 3 index value:
# Indexing a named tuple
print(nik[3])
# Returns: datagy
Now that you’ve learned how to create a Python named tuple, let’s explore some of the differences between named tuples and regular tuples.
How Python Named Tuples are different from regular tuples
Python namedtuples
are a subclass of regular tuples. We can verify this by using the issubclass()
function.
# Checking if named tuples are a subclass
print(issubclass(Person, tuple))
# Returns: True
What this means is that named tuples inherit all behaviors of regular tuples, but also extend them. The table below provides an overview of the key differences and similarities between them:
Tuples
- Immutable
- Indexable
- Heterogeneous
- Iterable
Named Tuples
- Immutable
- Indexable
- Heterogeneous
- Iterable
- Can be converted to dictionaries easily
- Provides additional methods to make working with them easier
- Can access a value with dot notation
What the table above illustrates is that named tuples are an extension of regular tuples. They can make your life coding much simpler and they greatly increase the readability of anyone reading your code.
When to use a Python named tuple over different data structures
At this point, you have a strong understanding of how named tuples may be more beneficial to use than regular tuples. You may also have noticed that named tuples are beginning to look a lot like dictionaries.
For example, we could easily create a dictionary looks like our named tuple:
# Creating a namedtuple
from collections import namedtuple
Person = namedtuple('Person', ['name', 'age', 'location', 'profession'])
nik = Person('nik', 33, 'Toronto', 'datagy')
# Creating a dictionariy
nik_dict = {'name': 'Nik', 'age': 33, 'location': 'Toronto', 'profession': 'datagy'}
# Accessing values works the same
print(nik.profession)
print(nik_dict['profession'])
# Returns:
# datagy
# datagy
At this point, you may be asking why you’d want to choose either a dictionary or a named tuple? Dictionaries are mutable and tuples are immutable. If you need to modify your object after creating it, a dictionary make work better for you. Similarly, if you don’t want to modify your object, accidentally or otherwise, a named tuple may work better.
Because of its immutability, named tuples also use less memory than dictionaries. This can be helpful when working with larger items or many items.
Provide Default Values to a Python Named Tuple
One of the great features of a named tuple is the ability to provide default values. This extends the analogy of the named tuple being similar to a class. In this section, you’ll learn how to create default values and how these values behave in a named tuple.
In Python named tuples, fields with default values must come after fields that don’t have default values. This means that the default values are applied to the right-most parameters.
Let’s take a look at an example. We’ll recreate our earlier named tuple and provide some default values:
# Providing default values to a named tuple
from collections import namedtuple
Person = namedtuple('Person', ['name', 'age', 'location', 'profession'], defaults=['Toronto', 'Coding'])
nik = Person('Nik', 33)
print(nik.profession)
# Returns: Coding
Notice that we didn’t specify for what field names the default values should be provided. Because we specified only two default values, they were assigned to the two right-most field names: location
and profession
.
This, in turn, means that name
and age
are mandatory. Let’s see what happens when we only pass in a name:
from collections import namedtuple
Person = namedtuple('Person', ['name', 'age', 'location', 'profession'], defaults=['Toronto', 'Coding'])
nik = Person('Nik')
# Raises: TypeError: __new__() missing 1 required positional argument: 'age'
If you’re ever confused as to what the default values are, you can use the _field_defaults
attribute. This returns a dictionary of field names and their associated default values:
# Checking default values for field names
from collections import namedtuple
Person = namedtuple('Person', ['name', 'age', 'location', 'profession'], defaults=['Toronto', 'Coding'])
print(Person._field_defaults)
# Returns:
# {'location': 'Toronto', 'profession': 'Coding'}
Replace Values in a Python named tuple
Since named tuples are immutable, it may seem counterintuitive to include a section on replacing values in them. However, the namedtuple
object comes with a method, ._replace()
, which allows you to replace values in a named tuple.
The way that this works, behind the scenes, is that the original named tuple is destroyed and a new named tuple is created.
The benefit of this approach is that it allows us to modify only specific values, while retaining the original values. Let’s see how this works:
# Replacing values in a named tuple
from collections import namedtuple
Person = namedtuple('Person', ['name', 'age', 'location', 'profession'])
Nik = Person('Nik', 33, 'Toronto', 'datagy')
print(Nik.age)
Nik = Nik._replace(age=34)
print(Nik.age)
# Returns:
# 33
# 34
What is great about this approach is that we can leave values we want unchanged, unchanged.
We can confirm that the original tuple is destroyed and that a new one is created by using the id()
function:
Nik = Person('Nik', 33, 'Toronto', 'datagy')
print(id(Nik))
Nik = Nik._replace(age=34)
print(id(Nik))
# Returns:
# 140389596252496
# 140389596252976
Since the IDs of the two objects differ, we know that a new named tuple was created when the ._replace()
method was called.
Convert a named tuple to a Python dictionary
Python named tuples have a lot in common with dictionaries. Because of this, the collections
module provides an easy way to convert a named tuple into a dictionary.
Let’s see how we can use the ._asdict()
method to convert a named tuple into a dictionary:
# Converting a named tuple to a dictionary
from collections import namedtuple
Person = namedtuple('Person', ['name', 'age', 'location', 'profession'])
Nik = Person('Nik', 33, 'Toronto', 'datagy')
Nik_dict = Nik._asdict()
print(Nik_dict)
# Returns:
# {'name': 'Nik', 'age': 33, 'location': 'Toronto', 'profession': 'datagy'}
This can be an incredibly helpful way to convert between data types.
Safely Replace Labels in a Named Tuple
One of the constraints placed on field names in named tuples is that they cannot be reserved keywords. When you’re manually creating a named tuple, this can be an easy limitation to overcome.
However, if you’re creating named tuples when reading files, this can prove to be a real limitation. We’ll pass in a list of field names that contains a reserved keyword, from
.
# Using a reserved field name
from collections import namedtuple
field_names = ['from', 'age', 'location']
Person = namedtuple('Person', field_names=field_names)
# Raises: ValueError: Type names and field names cannot be a keyword: 'from'
We can see that using a reserved keyword as a field name raises a ValueError
. When you’re loading data programatically, this can be a major limitation, since you may not want to directly intervene in naming your field names.
In order to circumvent this, we can use the rename=True
argument when creating a named tuple:
# Using rename=True to handle reserved field names
from collections import namedtuple
field_names = ['from', 'age', 'location']
Person = namedtuple('Person', field_names=field_names, rename=True)
print(Person._fields)
# Returns: ('_0', 'age', 'location')
The reserved field names are replaced with field names starting at _0
.
Do Named Tuples Use More Memory?
Python named tuples do not use more memory than regular Python tuples. Aside from the additional code overhead of creating the named tuple definition, there are no real downsides to using named tuples over regular tuples. In fact, named tuples serve to make your code much more readable.
Conclusion
In this tutorial, you learned how to create a Python named tuple using the collections module. You learned how to create named tuples and how to access their properties using index and field name labels. You learned the differences between regular tuples and named tuples, as well as how named tuples simply extend the attributes of regular tuples.
You then learned how to use special methods and parameters of named tuples to extend their utility. This included providing default values and handling reserved field names. You also learned how to convert named tuples into dictionaries.
Additional Resources
To learn more about related topics, check out the tutorials below:
Excellent site. Thank you.
Just to make it better I point to one mispelling:
Can be any of the following:
1. A list of strings ([‘a’, ‘b’, ‘c’])
2. A string seperated by spaces (‘a b c’)
3. A string seperated by commas (‘a, b, c’)
(separated)
Thank you so much!! I have fixed that :).