Tuple
A set is a built-in data structure in Python and is classified as a type of sequence data structure.
Characteristics
- Immutable Sequence
- Container Sequence
- Can be used as record
- Just the tuple object is immutable, the tuple's element can change.
- Use parentheses ()
- Usually contain a heterogeneous sequence
The Tuples references to Mutable Objects
Basic concepts:
The concept of immutability in tuples specifically pertains to the tuple's references. It's crucial to note that while tuples themselves are immutable, this immutability does not extend to the mutable objects they may reference. Care should be taken when dealing with tuples containing mutable items to avoid potential sources of bugs.
>>> a = (10, 'alpha', [1, 2])
>>> b = (10, 'alpha', [1, 2])
>>> print(f"a == b? {a == b}, A type = {type(a)} and B type = {type(b)}")
>>> b[-1].append(99)
>>> print(f"a == b? {a == b}")
>>> print(f"A now: {a} vs B now: {b}")
a == b? True, A type = <class 'tuple'> and B type = <class 'tuple'>
a == b? False
A now: (10, 'alpha', [1, 2]) vs B now: (10, 'alpha', [1, 2, 99])
Tuples as Records
If you are familiar with the structure of tuple objects, you can utilize tuples as record data, with each item in the tuple representing data for a specific field. The sequence of items holds significance, and the count of fields remains constant.
>>> countries_nationality = [('Chile', 'Chilean'), ('Brazil', 'Brazilian'), ('Argentina', 'Argentine'), ('Uruguay', 'Uruguayan')]
>>> for country, nationality in countries_nationality:
... print(f"Country field: {country}, Nationality: {nationality}")
Country field: Chile, Nationality: Chilean
Country field: Brazil, Nationality: Brazilian
Country field: Argentina, Nationality: Argentine
Country field: Uruguay, Nationality: Uruguayan
Tuples vs Lists
Using Tuples instead of Lists can bring both performance benefits and clarity to your code:
- Clarity: When you encounter a tuple in the code, you can be certain that its
length will remain constant. - Performance:
Tuples consume less memorycompared to a list of equivalent length, enabling Python to implement optimizations.
A deeper discussion can be found here in this StackOverflow answer by Python core developer Raymond Hettinger
A deeper discussion can be found here in this StackOverflow answer provided by Raymond Hettinger, a Python core developer.
Named Tuples
Named tuples in Python offer a way to create tuples that enable you to access values using descriptive field names and the dot notation, instead of relying on ambiguous integer indices.
collections.namedtuple
Python's namedtuple() resides within the collections module as a factory function. It empowers you to generate subclasses of tuples, complete with named fields. This offers supplementary methods and attributes like ._make(), _asdict(), and ._fields, among others. Notably, named tuples maintain backward compatibility with conventional tuples while exhibiting comparable memory usage.
>>> from collections import namedtuple
>>> Point = namedtuple("Point", "x y")
>>> print(f"Is subclass of tuple? {issubclass(Point, tuple)}")
>>> point = Point(2, 4)
>>> print(point, point.x, point.y)
>>> print(point, point[0], point[1])
Is subclass of tuple? True
Point(x=2, y=4) 2 4
Point(x=2, y=4) 2 4
For further customization, including required and optional arguments, along with other details, see the the Real Python article.
typing.NamedTuple
Within the typing module, there exists NamedTuple, a typed variant of namedtuple. This allows to craft namedtuple classes with type annotations. Notably, both namedtuple and NamedTuple instances exhibit identical memory consumption characteristics.
>>> from typing import NamedTuple
>>> class Person(NamedTuple):
... name: str
... age: int
... country: str = "Canada"