🐍 Python - Tuples
Tuples
Updated at 2018-06-09 17:24
Tuples are immutable sequences of data. You use both tuples and named tuples to enforce a better structure for your data that is not complex enough to create a class for it.
from typing import Tuple
my_tuple: Tuple[int, int, int] = (1, 2, 3)
my_tuple[0] = 3 # => TypeError: 'tuple' object does not support item assignment
Non-empty tuples are always truthy in Python.
assert bool(()) is False
assert bool((0,)) is True
assert bool((False,)) is True
assert bool((None,)) is True
assert bool((0, None, False)) is True
Tuples unpack without much effort. Even with nested tuples.
from typing import List, Tuple
cities: List[Tuple[str, Tuple[float, float]]] = [
('Tokyo', (35.68, 139.69)),
('Mexico City', (19.43, -99.13)),
]
for city, (latitude, longitude) in cities:
assert type(city) == str
assert type(latitude) == float
assert type(longitude) == float
# creates tuples by default if you leave out the parentheses
a, b, c = (1, 2, 3)
d, e, f = 4, 5, 6
Named tuples are "memory-efficient classes". The underlying implementation is a Python class so you can inherit from them or even add methods to them with inheritance.
from collections import namedtuple
Car = namedtuple('Car', ['color', 'mileage'])
assert Car._fields == ('color', 'mileage')
my_car = Car(color='blue', mileage=99)
assert my_car.color == my_car[0] == 'blue'
assert my_car.mileage == my_car[1] == 99
class SportsCar(Car):
def engine_sound(self) -> str:
return f'{self.__class__.__name__}: VROOM'
my_sports_car = SportsCar('red', 1000)
assert my_sports_car.color == my_sports_car[0] == 'red'
assert my_sports_car.mileage == my_sports_car[1] == 1000
assert my_sports_car.engine_sound() == 'SportsCar: VROOM'
Tuples and named tuples are both immutable. Write once, read many times. But you can duplicate and modify tuples.
from collections import namedtuple
Car = namedtuple('Car', ['color', 'mileage'])
c1 = Car(color='red', mileage=100)
c2 = c1._replace(color='purple')
assert c1.color == 'red' and c1.mileage == 100
assert c2.color == 'purple' and c2.mileage == 100
You can also use the NamedTuple class.
from typing import NamedTuple
class Car(NamedTuple):
color: str
mileage: float
automatic: bool
car1 = Car(color='red', mileage=123.45, automatic=True)
assert car1.mileage == 123.45
# car1.mileage = 1.15 # => AttributeError: can't set attribute
# car1.status = 'broken' # => AttributeError: 'Car' object has no...
Source
- Python Tricks The Book, Dan Bader
- Fluent Python, Luciano Ramalho