tuple#

tuple is Python’s immutable, ordered sequence. Two natural uses: a fixed-shape record ((host, port, scheme)) and a lightweight return-multiple-values vehicle. Hashable when all elements are hashable, so tuples can sit in set or as a dict key.

Literal forms.

Form

Example

Notes

Standard

(1, 2, 3)

Parens plus comma-separated values.

One-tuple

(42,)

The trailing comma is required.

Empty

()

Empty tuple.

Implicit

10, 20

Parentheses are optional in many places.

Unpacking binds names to positions.

Standard positional unpack.

x, y, z = (1, 2, 3)

Head plus tail with *.

host, *rest = ("a", 1, "tls")

Tuples support indexing, slicing, in, len, and the boolean / comparison operators. They have no append or sort because they are immutable; build a new tuple if needed. Examples assume t = (1, 2, 3).

Operation

Example

Result

Index

t[0]

1

Negative index

t[-1]

3

Slice

t[1:]

(2, 3)

Concat

t + (4, 5)

(1, 2, 3, 4, 5)

Sort

sorted(t)

[1, 2, 3] (a new list, not a tuple)

A namedtuple gives a tuple with field names. Reach for it when the record’s positions would otherwise be cryptic; reach for @dataclass when the record needs methods or mutation.

from collections import namedtuple
Target = namedtuple("Target", "host port scheme")
t = Target("example.com", 443, "https")
t.host                        # "example.com"

Method catalog#

tuple is immutable, so the method surface is tiny. The operator’s daily work is unpacking and indexing, both of which are syntax, not method calls.

Method

Effect

index(x[, start[, end]])

First index of x; raises ValueError on miss.

count(x)

Number of occurrences.

namedtuple adds these.

Method

Effect

_replace(**changes)

Return a new namedtuple with named fields replaced.

_asdict()

Return an OrderedDict of field-name to value.

_make(iterable)

Build a namedtuple from an iterable (classmethod).

_fields

Tuple of field names.

_field_defaults

Dict of field-name to default value.

index finds a value’s first position; raises if missing.

("a", "b", "c", "b").index("b")
1

count counts occurrences.

("a", "b", "c", "b").count("b")
2

_replace on a namedtuple returns a new instance with one field changed; the original is unchanged.

from collections import namedtuple
Target = namedtuple("Target", "host port")
Target("example.com", 80)._replace(port=443)
Target(host='example.com', port=443)

Operator overloading#

tuple implements the immutable-sequence dunders.

Operator

Dunder

Returns

a + b

__add__

New tuple (concatenation).

a * n

__mul__

Repeated tuple.

a == b

__eq__

Element-wise equality.

a < b

__lt__

Lexicographic less than.

a in b

__contains__

Element membership.

a[i] / a[i:j]

__getitem__

Indexing and slicing.

len(a)

__len__

Length.

iter(a)

__iter__

Iteration.

hash(a)

__hash__

Hash (when elements are hashable).

bool(a)

__bool__

False only for the empty tuple.

A frozen dataclass behaves like a named, hashable record; __eq__ and __hash__ are auto-generated from the fields.

from dataclasses import dataclass

@dataclass(frozen=True)
class Point:
    x: int
    y: int

Point(1, 2) == Point(1, 2), {Point(1, 2)} == {Point(1, 2)}
(True, True)

Tuples compare lexicographically, position by position; the operator gets multi-key ordering for free.

sorted([(2, "b"), (1, "z"), (2, "a")])
[(1, 'z'), (2, 'a'), (2, 'b')]

References#