Quantcast
Channel: Like Geeks
Viewing all articles
Browse latest Browse all 104

Python namedtuple (Take the tuple to the next level)

$
0
0

Python’s collections module is rich in classes and data structures that make the developer’s tasks easy for properly organizing data. Again, writing a Pythonic-style program by leveraging efficient data structure and sequence is also what we can get through the collections class.

In Python, you must have used the tuple sequence data type that stores heterogeneous values but that does not allow you to modify the data and its structure once created.

It restricts the modification because it is immutable in nature. However, the use of traditional Python tuples may reduce the code readability & makes it intricate to access elements with index values.

That is where the namedtuple comes as a convenient solution. In this article, you will learn about this special type of tuple called nametuple that allows programmers to use a Pythonic style programming.

 

 

What is a namedtuple?

A namedtuple is a type of data structure that comes as a class under the collection module that leverages the characteristics of a Python tuple (heterogeneous and immutable) while enhancing the readability like that of a Python dictionary.

It has a remarkable design that helps make the code more Pythonic.

Through Namedtuple, you can create an immutable sequence type that enables you to use the values through descriptive field names & the dot notation rather than complex integer indices (positive and negative).

In other words, namedtuple acts as an intermediate data structure between a tuple and a dictionary that store values under the namedtuple name with various field names as attributes.

We can import the collections module and use the namedtuple() method to create a name-based tuple. Let us take a closer look at how to implement it with a code snippet.
Example:

import collections

Employee = collections.namedtuple('Employee', ['name', 'designation', 'salary'])

# Including values
E = Employee('Karlos', 'Sr. Full-stack Engineer', '2800000')

# Accessing data using index
print("The Employee's designation is : ", end="")

print(E[1])

# Accessing data using name
print("The Employee's name is : ", end="")

print(E.name)

# Accessing data using getattr()
print("The Employee's salary is : ", end="")

print(getattr(E, 'salary'))

Output

This output shows how to implement NamedTuple in Python
From the above code, you can notice that we have created a namedtuple with the name Employee that has name, designation, and salary as three different named keys.

Then we use the Employee under the variable name E to create and assign its values. Now, you can notice that there are three different ways to access the values of a namedtuple.

One by using the index notation with the integer within it, as we do with tuple usually; the other way is to access it via the name and dot notation (E.keyName).

The final approach is through the get-attribute (getattr() function) that will take two parameters – one the variable name of the namedtuple followed by the attribute name that is there in the named tuple (here salary) separated by a comma (as usual).

 

When should we use the namedtuple?

The fundamental goal of using namedtuple is to implement immutable tuple with field names so that we can write Pythonic code.

This factory function (namedtuple()) was explicitly created to define & write readable, clean, and maintainable code in Python.

Apart from that, there are certain use cases of namedtuple for which it became well-known among developers.

  1. If you want to use field names instead of indices for accessing values from large heterogeneous data structures or making your code readable & flexible, this data structure can save your day.
    import collections
    
    Employee = collections.namedtuple('Employee', ['name', 'designation', 'salary'])
    
    E = Employee('Karlos', 'Sr. Full-stack Engineer', '2800000')
    
    print(E[1])
    
    # Accessing data using field name
    print("The Employee's name is : ", end="")
    
    print(E.name)

    Output

    This output shows when users should use NamedTuple in Python

  2. Another situation where namedtuple becomes beneficial is when you want to return multiple values from functions. Let us take an example and see how it works.
    from collections import namedtuple
    
    def multiRet_divmod(g, k):
    
        Div_Mod = namedtuple("Div_Mod", "QuotientValue RemainderValue")
    
        return Div_Mod(*Div_Mod(g, k))
    
    print(multiRet_divmod(16, 3))

    Output

    This output shows when users should use NamedTuple in Python

  3. Reducing the number of arguments in a function is another benefit you can get using namedtuple. Reducing the argument count will make the program more efficient, making it the best programming practice.
  4. Modern database management systems often use namedtuples to read tabular data from database tables and files. Let us download and use a CSV file and check how it works.
    import csv
    
    from collections import namedtuple
    
    with open("employees.csv", "r") as csv_fyl:
    
        reader = csv.reader(csv_fyl)
    
        EmployeeDat = namedtuple("EmployeeDat", next(reader), rename=True)
    
        for row in reader:
    
            employee = EmployeeDat(*row)
    
            print(employee.FIRST_NAME, employee.LAST_NAME, employee.JOB_ID)

    Output

    This output shows when users should use NamedTuple in Python

 

Why people don’t like namedtuple?

Programmers and developers do not like namedtuples because they seem challenging for individuals to learn & implement for beginners.

Also, programmers who have programming backgrounds in C, C++, Java, C#, etc. or are familiar with Python tuple know how easy tuple becomes when creating multiple values with parentheses or accessing the values with indexes.

Also, it becomes a tough nut to crack for newbie who wants to return multiple values from a function using namedtuple.

Therefore, expert programmers recommend frequently using it & making it a habit to use namedtuple as it will give you the potential of both tuple and dictionary-like storage.

 

Create a Python namedtuple

We must have to import the namedtuple from collections, which is a Python’s built-in module.

from collections import namedtuple  or import collections as col

Then we have to use the basic syntax for constructing a namedtuple:

namedtuple(Tuple_Name, [Names of all values])

Here, Tuple_Name it is an essential parameter that helps in providing the title/name we want to give to our namedtuple, and [Names of all values] acts as a placeholder for the list of all the names of different values or attributes that the namedtuple will hold.
Here is a code snippet showing how to use it:

import collections  

#creating Exchange Student namedtuple  
xchngStud = collections.namedtuple('ExchngStud', ['Name', 'Age', 'Country'])  

#Adding 2 exchnge Student details
g = xchngStud('Deeksha', '27', 'India')  

k = xchngStud('Sue', '25', 'Canada')  

#Accessing the items using indexing notation  
print( 'The name & country of the first exchange student is: ' + g[0] + ' and ' + g[2])  

#Accessing the items using field name   
print( 'The name & country of the exchange student is: ' + k.Name + ' and ' + k.Country)  

#Accessing the items using the getattr() method
print( 'The Age of both exchange students are: ' + getattr(g, 'Age') + ' and ' + getattr(k, 'Age'))

Output

This output shows how to create a NamedTuple in Python

 

Why does the first entry in a namedtuple has to be name of item?

The first parameter is always the name because, without the name, the namedtuple cannot create any placeholders for storing different values associating it.

It also gives a clear indicator that the namedtuple will have this name followed by the set of fields or names of values or attributes that the namedtuple will hold.

Now, based on that name, you can create the namedtuple & assign values respectively to the field names mentioned.

from collections import namedtuple

Language = namedtuple('Language' , ['name', 'creator'])

l1 = Language('C', 'Dennis Ritchie')

l2 = Language('Python', 'Guido V. Rossum')

print(l1)

print(l2)

Output

This output shows the first entry in a namedtuple have to be name of item in Python

 

Creating Python’s namedtuple from a list

We can pass a list full of strings to make them fields or placeholder for listing all the names that different values within the namedtuple.

We can use the namedtuple._make() to convert a list to namedtuple & can store it in a separate variable so that we can access it using the name of the values.

Here is a code snippet showing how we can use lists for creating values of a namedtuple.

from collections import namedtuple

Coder = namedtuple('Coder', ['Karlos', 'Ray', 'Dee'])

lipos = ['1st', '2nd', '3rd']

Coder._make(lipos)

Coder(Karlos = '1', Ray = '2', Dee = '3')

c = Coder._make(lipos)

print(c)

print(" 1st value of the list is:", c.Karlos)

Output

This output shows Creating Python's namedtuple from list in Python

 

Creating Python’s namedtuple from a tuple

We can pass a tuple full of strings to make them as fields or placeholder (taking it as the 2nd parameter) for listing all the names that different value within the namedtuple.

We can use the namedtuple._make() to convert a tuple to namedtuple & can store it in a separate variable so that we can access it using the name of the values.

Here is a code snippet showing how we can use tuples for creating values of a namedtuple.

from collections import namedtuple

tup = ("ID", "EmpName", "Salary")

Record = namedtuple("Record", tup)

tuple_pi = (1, "Karlos", 2650000)

print(Record(*tuple_pi))

print(Record._make(tuple_pi))

Output

This output shows Creating Python's namedtuple from tuple in Python
Here you can see two different notations programmers can use to access and use tuples within a namedtuple’s name.

 

Creating Python’s namedtuple from a dictionary

We can also create a namedtuple from a dictionary. We have to provide a namedtuple a name using string in the first parameter and use the dictionary_name.keys() to consider them as named values in the second parameter.

Here is a program that uses a function and will pass the dictionary object for the keys as namedtuple fields.

from collections import namedtuple

def convert(dictionary):

    return namedtuple('NamedDict', dictionary.keys())(**dictionary)

d = {"a":1, "b":2, "c":3}

nd = convert(d)

print(nd.a)

print(nd.b)

print(nd.c)

Output

This output shows Creating Python's namedtuple from dictionary in Python

 

What does namedtuple return?

Namedtuple usually returns the values with keys as an OrderedDict type object in a Python program.

For making it an OrderedDict, we need to utilize the _asdict() method. Here is a code snippet showing the use of _asdict() method.

import collections as col

Empl = col.namedtuple('EmployeeData', ['name', 'designation', 'salary'])

lst = ['Ray', 'Researcher', '25000']

e1 = Empl._make(lst)

print(e1)

dict1 = {'name':'Karlos', 'designation' : 'Data Analyst', 'salary' : '80000'}

e2 = Empl(**dict1)

print(e2)

# Showing the namedtuple as dictionary
emp_dict = e1._asdict()

print(emp_dict)

Output

This output shows what namedtuple return in Python

 

Iterate over namedtuple fields

Fields of a namedtuple are nothing but the second parameter that we have passed right after the tuple-name (the first parameter).

We can easily iterate over the fields and access them using the namedtuple._fields attribute and use it within for loop. Here is a code snippet showing how to use it.

from collections import namedtuple

letters = namedtuple('Letters', ['w', 'x', 'y', 'z'])(1, 2, 3, 4)

print("Iterating over fields")

for k in zip(letters._fields):

    print(k)

Output

This output shows how namedtuple iterate over fields in Python

 

Sort a simple namedtuple

We can use the sorted() function to easily sort a large namedtuple. The sorting can be done either numeric or alphabetically.

Here is a code snippet showing how to sort namedtuple:

from collections import namedtuple

Language = namedtuple('Language' , ['name1', 'name2', 'name3', 'name4', 'name5', 'name6'])

l1 = Language('C', 'Java', 'Go', 'R', 'C++', 'JavaScript')

print(sorted(l1))

Output

This output shows how to sort a simple namedtuple in Python

 

Sort a list of namedtuples

We can sort a list of namedtuples by implementing the itemgetter module. Here is a code snippet showing how we can do that:

from operator import itemgetter

from collections import namedtuple

Employee = namedtuple('Employee', 'name age score')

seq = [

    Employee(name = 'Karlos', age = 23, score = 100),

    Employee(name = 'Ray', age = 25, score = 200),

    Employee(name = 'Dee', age = 28, score = 300),

]

# sort list by employee Name
print(sorted(seq, key = itemgetter(Employee._fields.index('name'))))

# sort list by Employee's age
print(sorted(seq, key = itemgetter(Employee._fields.index('age'))))

Output

This output shows how to sort list namedtuple in Python
In the above program, we have sorted the values first based on the field “name” and then based on the field “age.”

 

Print certain value of a namedtuple

Printing specific values of a named tuple is easy if you know how to access them.

Named values allow you to access data using the usual approach, i.e., through the index numbering notation, via the field name, or using the getattr() function.

Now, we can use the popular print() function of Python to print it. The code snippet looks like this:

import collections

Employee = collections.namedtuple('Employee', ['name', 'designation', 'salary'])

# Including values
E = Employee('Karlos', 'Sr. Full-stack Engineer', '2800000')

# Accessing data using index and printing it
print("The Employee's designation is : ", end = "")

print(E[1])

# Accessing data using field name and printing it
print("The Employee's name is : ", end = "")

print(E.name)

# Accessing data using getattr() function and printing it
print("The Employee's salary is : ", end = "")

print(getattr(E, 'salary'))

Output
This output shows print certain values of namedtuple in Python

Here I’m access and printing the three different values ‘Karlos’, ‘Sr. Full-stack Engineer’, and ‘2800000’ associated with three different field names ‘name’, ‘designation’, and ‘salary’ respectively.

 

Add new fields into a namedtuple

Adding a new field to the named tuple is not possible. It is because, like Tuples, Namedtuples are also immutable. Once they get created, there is no way to change them.

You have to recreate them with a new memory reference or name and use the previous field names along with the new ones.

Here is a code explaining what a new reference will look like:

from collections import namedtuple

result = namedtuple('Result', ['g', 'k'])

G = result(2, 6)

print(G)

# We need to add one more field
result = namedtuple('Result',['g', 'k', 'r'])

# the above line will create a new reference for the result identifier
GR = result(2, 4, 6)

print(GR)

print(G)

Output
This output shows how add new fields into namedtuple in Python
Since, it shows two values, it makes clear that both the Result are using two different references in memory and are different entities/objects of a this program.

 

Replace an item in a namedtuple

We can simply use the assignment operator to set new values to an existing namedtuple after the field named gets initialized.

The _replace() method helps in updating the existing value of a field with a new value and returning a new namedtuple. It is also called namedtuple value updating. Here is a simple code snippet explaining you on how to do that.

from collections import namedtuple

Emp = namedtuple('Emp', 'g, k')

e = Emp(g=16, k=26)

print (e)

print(e._replace(g = 36))

Output

This output shows how to replace item in namedtuple in Python

 

Change namedtuple within a namedtuple

Since namedtuples are immutable in nature, it is not possible to change the namedtuple within namedtuple or its named fields once it gets created and assigned a reference memory.

 

Make namedtuple within a list

To make a namedtuple within a list, we have to create a namedtuple object and pass it as one of the elements within the list. Here is a code snippet on how to do that.

from collections import namedtuple

Emp = namedtuple('Emp', 'g, k')

e = Emp(g = 16, k = 26)

li=[1, 2, 43, 4, e]

print ("Printing the named tuple:", e,"\n")

print("Printing the list containing namedtuple:")

print(li)

Output

This output shows how to make namedtuple within list in Python

 

Assign attributes from within a namedtuple

We can assign values to the namedtuple within the namedtuple. We can also assign all the attribute values at a time. Here is a code snippet showing how to do that –

import collections

Details = collections.namedtuple('Details',['sender','receiver','date','amount'])

record = Details(sender="Ray", receiver = "karlos", date = "2022-07-20", amount = 1.0)

print(record.receiver)

print(record[1])

sender, receiver, date, amount = record

print(receiver)

print(record._asdict())

Output

This output shows how to assign attributes from within namedtuple in Python

 

Tuple vs. namedtuple

Although, both tuples and namedtuples are immutable in nature, there are certain differences exist between them.

Tuple Namedtuple
Tuple values are like normal values without any descriptive field names. Namedtuples allow users to assign values against descriptive field names.
Value accessibility becomes possible only through index notation. Value accessibility becomes easy through index notation, field name, and getattr() function.
Tuples can store multiple items or elements under a single variable name called tuple object. Namedtuple acts as an intermediate data structure between a tuple and a dictionary that store values under the namedtuple name with various field names.
Tuple is a part of the standard library and do not need to import any module separately. For using namedtuple, programmers have to import the collections module separately.

 

Namedtuple vs. dictionary

Namedtuple Dictionary
Namedtuple is an immutable data structure. Dictionary is a mutable data structure.
In the namedtuple, field names and field values works in combination to store each element within the namedtuple. In the Python dictionary, the key: value pairing helps in determining each element of the dictionary under a single variable name, also called the dictionary object.
Namedtuple is a pure sequence data structure, i.e., we can iterate over each element through indexing. Dictionary is not a sequence. We can iterate over each element but since, it is not indexed but shows element uniqueness based on keys, it cannot be iterated normally.
For using namedtuple, programmers have to import the collections module separately. Dictionary is a part of the standard library and do not need importing module separately.

 

Python Enum vs. Namedtuple

Enum Namedtuple
Enum is a separate data structure from a separate module called Enum. Namedtuple is a data structure that resides within the collections module.
You can create enumerations in Python using classes. Namedtuples does not need the support of classes for using it.
It is suitable for hashing. It is not suitable for hashing.

 

Namedtuple vs. Dataclass

Namedtuple Dataclass
Namedtuple is faster compared to dataclass when it comes to namedtuple creation. Dataclass is slower compared to namedtuple when it comes to dataclass creation.
Reading elements and objects is slower in this case. Reading elements and objects is faster in this case.
It is immutable in nature. It is mutable in nature.
It does not cater to much value while dealing with inheritance. It provides better inheritance support.
The implementation of namedtuple is inherited from Tuple which is created using C. The implementation of dataclass is written in Python.
It is better for exploding and unpacking. It is faster and more flexible for dynamic data.

 

Conclusion

We hope this article has given a crisp idea of what namedtuple is and how it is advantageous to a Python tuple.

Also, this article gave us a clear insight on how to create a namedtuple, assign values, and access elements differently from a namedtuple.

Namedtuple is beneficial because even though it is immutable, it acts as an intermediate data structure between tuple and dictionary.

Then, we came across how to iterate namedtuples over fields and print certain values of namedtuples.

We have also encountered how to replace an item in namedtuple and create namedtuple within a list.

Lastly, we went through the differences between tuple and namedtuple, namedtuple and dictionary, enumeration and Namedtuple, and namedtuple and Dataclass.


Viewing all articles
Browse latest Browse all 104

Trending Articles