Named Tuples vs Dataclasses in Python: Which One Should You Use?
Understanding two powerful ways to create structured data in Python, with examples, differences, and practical use cases.
Introduction
Python is known for its simplicity, readability, and flexibility. One of its strengths is the ability to represent structured data without writing lengthy classes or complicated boilerplate code. When working with related information, such as a student’s name, roll number, and marks, developers often need a clean way to organize that data.
Python provides several options for this purpose, including dictionaries, tuples, named tuples, and classes. Two particularly useful approaches are Named Tuples and Dataclasses.
At first glance, both may appear similar because they allow us to group related values under meaningful field names. However, they differ in mutability, available features, implementation, and ideal use cases.
In this blog, we will explore what named tuples and dataclasses are, how they work, their key differences, and how to choose the right option for your Python project.
1. What Are Named Tuples in Python?
A named tuple is a tuple-like data structure that allows you to access elements using descriptive field names instead of relying only on numeric indexes.
Normally, a regular tuple looks like this:
student = ("Rahul", 101, 85)print(student[0]) # Rahul
print(student[1]) # 101Although this works, accessing values using indexes can make code harder to understand. For example, student[2] does not immediately tell us what the value represents.
A named tuple solves this problem by assigning names to the fields.
Python provides NamedTuple through the typing module.
Example: Creating a Named Tuple
from typing import NamedTupleclass Student(NamedTuple):
name: str
roll_no: int
marks: floatstudent = Student("Rahul", 101, 85.5)print(student.name)
print(student.roll_no)
print(student.marks)
Output:
Rahul
101
85.5Here, Student defines three fields: name, roll_no, and marks. We can access each value through its field name, making the code more readable.
Key Features of Named Tuples
- Immutable: Field values cannot be reassigned after an instance is created.
- Memory-efficient: They use tuple-based storage, which is useful for lightweight data records.
- Index access: Values can be accessed using either field names or numeric indexes.
- Tuple compatibility: They can be unpacked and used in many contexts that accept tuples.
- Type annotations: Fields can be annotated with types for better readability and static analysis.
For example:
print(student[0]) # Rahulname, roll_no, marks = student
print(name)However, attempting to change a field raises an error:
student.marks = 95This raises an AttributeError because named tuples are immutable.
Named tuples are particularly useful when you need a lightweight, structured record whose values should remain unchanged.
2. What Are Dataclasses in Python?
Dataclasses were introduced in Python 3.7 through the dataclasses module. They make it easier to create classes primarily intended to store data.
Before dataclasses, developers often had to write repetitive methods such as __init__() and __repr__() manually. Dataclasses can generate these methods automatically.
Example: Creating a Dataclass
from dataclasses import dataclass@dataclass
class Student:
name: str
roll_no: int
marks: floatstudent = Student("Rahul", 101, 85.5)print(student.name)
print(student.roll_no)
print(student.marks)
Output:
Rahul
101
85.5The result looks similar to the named tuple example. However, the implementation provides more flexibility.
The @dataclass decorator automatically generates an initializer and, by default, a useful string representation and equality comparison.
For example:
print(student)Output:
Student(name='Rahul', roll_no=101, marks=85.5)We did not have to write a constructor or a custom representation method ourselves.
Key Features of Dataclasses
- Mutable by default: Field values can be modified after object creation.
- Automatic methods: Common methods such as
__init__(),__repr__(), and__eq__()are generated by default. - Default values: Fields can have predefined values.
- Custom behavior: You can define your own methods just like in regular Python classes.
- Advanced options: Dataclasses support features such as frozen instances, keyword-only fields, and controlled comparison behavior.
For example, changing a student’s marks is straightforward:
student.marks = 95print(student.marks)Output:
95This makes dataclasses suitable for applications where data needs to change as the program runs.
3. Named Tuples vs Dataclasses: Key Differences
Although both structures organize data into named fields, their underlying behavior is different.
A. Mutability
The most important difference is whether an object’s fields can be changed.
Named tuples are immutable. Once an instance is created, its fields cannot be reassigned.
Dataclasses are mutable by default. Their attributes can be updated whenever required.
from typing import NamedTuple
from dataclasses import dataclassclass PointTuple(NamedTuple):
x: int
y: int@dataclass
class PointData:
x: int
y: intp1 = PointTuple(10, 20)
p2 = PointData(10, 20)p2.x = 50 # Allowed
# p1.x = 50 # Raises AttributeError
Choose named tuples when immutability is desirable. Choose dataclasses when the object’s state needs to change.
B. Memory and Performance
Named tuples are generally lightweight because they are tuple subclasses. They are a useful choice when representing many small, immutable records.
Dataclasses are ordinary classes by default. Their instances typically have an instance dictionary unless features such as slots=True are used.
However, actual memory usage and execution speed depend on the Python implementation, the fields, and the operations performed. It is better to benchmark your own workload than to assume one option is always faster.
Get Yugankcomp’s stories in your inbox
Join Medium for free to get updates from this writer.
Dataclasses also support slots:
from dataclasses import dataclass@dataclass(slots=True)
class Point:
x: int
y: intOn supported Python versions, slots=True can reduce per-instance memory overhead by avoiding a normal instance dictionary.
C. Default Values
Dataclasses make default field values straightforward.
from dataclasses import dataclass@dataclass
class Product:
name: str
price: float
in_stock: bool = Trueitem = Product("Keyboard", 1499.0)print(item.in_stock)
Output:
TrueNamed tuples also support defaults, but their traditional NamedTuple syntax has some ordering restrictions: fields with defaults must come after fields without defaults.
from typing import NamedTupleclass Product(NamedTuple):
name: str
price: float
in_stock: bool = TrueBoth approaches support defaults, but dataclasses offer additional control over field initialization.
D. Methods and Custom Logic
Dataclasses are especially useful when a data structure needs behavior in addition to storing values.
from dataclasses import dataclass@dataclass
class BankAccount:
owner: str
balance: float def deposit(self, amount: float):
if amount > 0:
self.balance += amountaccount = BankAccount("Aarav", 5000)
account.deposit(1000)print(account.balance)
Output:
6000You can also define methods on named tuples. However, their immutable fields make them less convenient when the behavior requires updating the stored state.
For example, a named tuple could calculate a value from its existing fields, but it could not directly modify those fields.
E. Equality and Object Behavior
Both structures support value-based equality, but their comparison rules differ.
Two dataclass instances of the same class are generally equal when their corresponding comparison-enabled fields are equal.
from dataclasses import dataclass@dataclass
class Point:
x: int
y: intprint(Point(2, 3) == Point(2, 3))
Output:
TrueNamed tuples also compare their values, but because they are tuples, their equality follows tuple comparison rules. A named tuple can compare equal to an ordinary tuple containing the same values.
from typing import NamedTupleclass Point(NamedTuple):
x: int
y: intprint(Point(2, 3) == (2, 3))
Output:
TrueThis distinction matters when designing APIs, tests, or data structures where the exact type of an object is important.
4. Comparison Table
FeatureNamed TuplesDataclassesIntroducedcollections.namedtuple in Python 2.6; typing.NamedTuple in Python 3.6Python 3.7MutabilityImmutable fieldsMutable by defaultAccessField names and indexesPrimarily field namesTuple compatibilityYesNoAutomatic initializerYesYesGenerated representationYesYes, by defaultDefault valuesSupportedSupportedCustom methodsSupportedSupportedMemory optimizationLightweight tuple-based storageSupports slots=TrueBest suited forLightweight, immutable recordsFlexible data models and application objects
The table highlights the general differences, but the best choice ultimately depends on how the data will be used.
5. When Should You Use Named Tuples?
Named tuples are a good option when your data represents a simple record that should not change.
Consider these situations:
1. Coordinates and geometric points
A coordinate such as (latitude, longitude) or (x, y) is often naturally represented as an immutable record.
2. Returning multiple values from a function
Named tuples allow a function to return several related values with descriptive names while retaining tuple unpacking.
3. Lightweight data records
If your application creates many simple records and benefits from tuple behavior, named tuples are worth considering.
4. Read-only configuration or result data
They can be helpful when you want to discourage accidental reassignment of fields.
For example, a function that calculates a student’s result could return a named tuple containing the student’s name, total marks, and percentage.
6. When Should You Use Dataclasses?
Dataclasses are a better fit when your objects need more flexibility or are part of a larger application.
1. Application models
Objects such as users, products, orders, and transactions often require defaults, methods, and mutable attributes.
2. Business logic
A product object might calculate discounts, an account might process deposits, or an order might update its status.
3. Complex data structures
Dataclasses support nested objects, field metadata, custom initialization, and other options that are useful as applications grow.
4. Validation and customization
You can implement __post_init__() to perform additional processing or validation after the generated initializer runs.
from dataclasses import dataclass@dataclass
class Product:
name: str
price: float def __post_init__(self):
if self.price < 0:
raise ValueError("Price cannot be negative")item = Product("Mouse", 799.0)
Here, the object checks its price immediately after initialization. This demonstrates how dataclasses can combine structured storage with application-specific rules.
Remember that type annotations alone do not automatically validate the types or values passed to either a named tuple or a dataclass.
7. Can Dataclasses Be Immutable?
Yes. Although dataclasses are mutable by default, you can make their fields non-reassignable through the frozen=True option.
from dataclasses import dataclass@dataclass(frozen=True)
class Employee:
name: str
employee_id: intemployee = Employee("Priya", 102)# employee.name = "Ananya" # Raises FrozenInstanceError
This is useful when you want dataclass features but also want to prevent ordinary reassignment of fields.
However, frozen dataclasses are not exactly the same as named tuples. A frozen dataclass is still a class instance, not a tuple, and its equality and storage behavior remain different.
Also, frozen=True does not make nested mutable objects deeply immutable. If a field contains a list, the list itself can still be modified.
8. Conclusion: Which One Is Better?
There is no universal winner between named tuples and dataclasses. Both are useful Python features, and understanding their differences helps you write cleaner, more maintainable code.
Choose Named Tuples when you need lightweight, immutable records with named fields, tuple unpacking, and compatibility with tuple-based operations.
Choose Dataclasses when you need flexible objects with default values, customizable behavior, mutable attributes, or more advanced data-modeling features.
For example, a coordinate returned by a calculation may work perfectly as a named tuple, while a shopping-cart item whose quantity and price change during checkout may be better represented by a dataclass.
The most important lesson is to choose the structure based on the requirements of your program rather than simply following a trend. Python gives you both options so that you can balance readability, flexibility, and performance.
As you build larger projects, experimenting with both approaches will help you understand how Python represents data and how thoughtful design choices can make your code easier to maintain.
Acknowledgment
This blog is created as part of learning at Pillai College of Engineering (PCE). For more details, visit https://www.pce.ac.in.




