Source

Why should you use namedtuple instead of a tuple?

Hi there guys! You might already be acquainted with tuples. A tuple is a lightweight object type which allows to store a sequence of immutable Python objects. They are just like lists but have a few key differences. The major one is that unlike lists, you can not change a value in a tuple. In order to access the value in a tuple you use integer indexes like:

man = ('Ali', 30)
print(man[0])
# Output: Ali

Well, so now what are namedtuples? They turn tuples into convenient containers for simple tasks. With namedtuples you don’t have to use integer indexes for accessing members of a tuple. You can think of namedtuples like dictionaries but unlike dictionaries they are immutable.

from collections import namedtuple

Animal = namedtuple('Animal', 'name age type')
perry = Animal(name="perry", age=31, type="cat")

print(perry)
# Output: Animal(name='perry', age=31, type='cat')

print(perry.name)
# Output: 'perry'

As you can see that now we can access members of a tuple just by their name using a .. Let’s disect it a little more. A named tuple has two required arguments. They are the tuple name and the tuple field_names. In the above example our tuple name was ‘Animal’ and the tuple field_names were ‘name’, ‘age’ and ‘cat’.

Namedtuple makes your tuples self-document. You can easily understand what is going on by having a quick glance at your code. And as you are not bound to use integer indexes to access members of a tuple, it makes it more easy to maintain your code. Moreover, as namedtuple instances do not have per-instance dictionaries, they are lightweight and require no more memory than regular tuples. This makes them faster than dictionaries.

However, do remember that as with tuples, attributes in namedtuples are immutable. It means that this would not work:

from collections import namedtuple

Animal = namedtuple('Animal', 'name age type')
perry = Animal(name="perry", age=31, type="cat")
perry.age = 42

# Output: Traceback (most recent call last):
#            File "<stdin>", line 1, in <module>
#         AttributeError: can't set attribute

You should use named tuples to make your code self-documenting. They are backwards compatible with normal tuples. It means that you can use integer indexes with namedtuples as well:

from collections import namedtuple

Animal = namedtuple('Animal', 'name age type')
perry = Animal(name="perry", age=31, type="cat")
print(perry[0])
# Output: perry

Last but not the least, you can convert a namedtuple to a dictionary. Like this:

from collections import namedtuple

Animal = namedtuple('Animal', 'name age type')
perry = Animal(name="perry", age=31, type="cat")
perry._asdict()
# Output: OrderedDict([('name', 'perry'), 
# ('age', 31), ('type', 'cat')])

I am sure that you learned a thing or two in today’s post! Let me remind you that I am writing a book on Python which would include things like this. If you want to be the first one to know when it comes out then signup to my mailing list. I also send out a weekly newsletter containing interesting and informative links related to Python which I come across every week. If you have any question then don’t hesitate to ask! I love to answer 🙂 You can approach me through Email, Twitter or Facebook. Goodbye!

Newsletter

×

If you liked what you read then I am sure you will enjoy a newsletter of the content I create. I am also publishing my "Practical Python Projects" book soon. To stay updated regarding the book and new posts, join 5000+ other people who receive my newsletter:

I send out the newsletter once every couple of weeks. No spam, I promise

✍️ Comments

Pedro Vagner

Hi, very well explained. Good luck with your book.

Yasoob
In reply to Pedro Vagner

Thanks! :)

Paul

Thank for a nice post. I’d have a follow up question - how easy it is to create a named tuple from a dictionary (with default values for example)? I have my workarounds but thought you may know better.

My use case is as follows: I’m using argparse library in my code. Unfortunately (!) they use named tuples too. All is well when I call my code through command line (all parameters are set and used in the code), but sometimes I want to use my code not through the command line. So what I want to do is to set just a few parameters in the named tuple and pass it along to the logic. Unfortunately it’s impossible - all parameters need to be set (even when not used in my logic).

So what I ended up doing is either expecting a dictionary or converting named tuple to a dictionary and then process. This ain’t elegant though in my view.

Would prefer argparse to use dictionaries…

Any hints are appreciated.

Thank you, Paul

Yasoob
In reply to Paul

Why not separate the argument parsing logic and the main code? Perhaps in two different functions? That way you can call the main code without the argument parsing logic getting in your way. What do you say?

Jan Stoker

I’ve always found namedtuple very useful. I have a slight preference for the syntax:

 Animal = namedtuple(‘Animal’, [‘name’,‘age’,‘type’]) 
Because it syntactically separates out the names of the fields.

Cuahutli

Hi,

Thank you for shared, i’m new reader in your blog, and this article is very useful for me.

Today Understood how they work namedTuple, The i will apply in my developments!!

Say something

Send me an email when someone comments on this post.

Thank you!

Your comment has been submitted and will be published once it has been approved. 😊

OK