Tuples et p-uplets nommés
Introduction
En mathématiques, un p-uplet est une collection ordonnée et finie de valeurs : un couple est un 2-uplet, un triplet un 3-uplet, et plus généralement un -uplet.
Python propose ce même outil sous le nom de tuple. C'est, comme la liste, une séquence ordonnée indexée par entiers — à une différence cruciale près : un tuple est non modifiable (on dit immuable ou immutable). Voir .
Créer un tuple
Un tuple s'écrit avec des parenthèses, les valeurs séparées par des virgules.
point = (3, 5)
print(point) # (3, 5)
print(type(point)) # <class 'tuple'>
print(len(point)) # 2
t = 1, 2, 3 est un tuple valide. Les parenthèses
sont vivement recommandées pour la lisibilité.L'accès à un élément se fait exactement comme pour une liste, avec des crochets et un index entier commençant à 0 :
point = (3, 5)
print(point[0]) # 3
print(point[1]) # 5
La différence clé : immutabilité
Contrairement à une liste, un tuple ne peut pas être modifié après création. Toute tentative d'affectation lève une erreur.
point = (3, 5)
point[0] = 10
# TypeError: 'tuple' object does not support item assignment
list | tuple | |
|---|---|---|
| Délimiteurs | [ ] | ( ) |
| Modification d'un élément | ✅ t[0] = v | ❌ erreur |
| Ajout d'un élément | ✅ t.append(v) | ❌ impossible |
| Suppression d'un élément | ✅ del t[0] | ❌ impossible |
| Accès par index | ✅ t[0] | ✅ t[0] |
Parcours for x in t: | ✅ | ✅ |
len(t) | ✅ | ✅ |
(année, mois, jour), un couple (login, mot_de_passe_haché). L'immutabilité protège
contre les modifications accidentelles et signale l'intention au lecteur du
code.Parmi ces expressions, laquelle lève une erreur ?
Usage canonique : renvoyer plusieurs valeurs
Un tuple permet à une fonction de renvoyer plusieurs valeurs liées, et à l'appelant de les récupérer en une seule affectation appelée affectation multiple (ou déballage, unpacking).
def division_euclidienne(a, b):
"""Renvoie le quotient et le reste de a par b."""
return (a // b, a % b)
q, r = division_euclidienne(17, 5)
print(q, r)
# Sortie : 3 2
Les parenthèses sont si naturelles ici qu'on peut même les omettre :
return a // b, a % b # exactement équivalent à return (a // b, a % b)
P-uplets nommés — namedtuple
Un tuple ordinaire a un inconvénient : ses champs n'ont pas de nom. Si
p = (48.85, 2.35), l'élève qui relit le code doit deviner que p[0] est la
latitude et p[1] la longitude.
La bibliothèque standard collections fournit un outil pour donner un nom à
chaque champ : namedtuple. Le résultat reste un tuple — donc immuable —
mais on accède aux champs par leur nom.
from collections import namedtuple
# 1. On définit le type : un Point a deux champs nommés x et y
Point = namedtuple("Point", ["x", "y"])
# 2. On crée des valeurs de ce type
p = Point(3, 5)
q = Point(x=10, y=12)
# 3. On lit les champs par leur nom — plus parlant que p[0]
print(p.x, p.y) # 3 5
print(q.x, q.y) # 10 12
# Les opérations habituelles d'un tuple restent valables
print(len(p)) # 2
print(p[0]) # 3 — l'accès par index marche aussi
namedtuple
est en pratique un compromis pratique entre les deux : la rigidité ordonnée
d'un tuple, la lisibilité nominale d'un dictionnaire.Comparaison rapide
# Tuple ordinaire — concis mais opaque
p = (48.85, 2.35)
print(p[0]) # 48.85 — quelle grandeur est-ce ?
# P-uplet nommé — explicite
Coord = namedtuple("Coord", ["latitude", "longitude"])
paris = Coord(48.85, 2.35)
print(paris.latitude) # 48.85 — aucun doute possible
Avec Point = namedtuple("Point", "x", "y") et p = Point(3, 5), que vaut p.y ?
Pièges courants
- Le tuple à un seul élément :
(42)n'est pas un tuple, c'est juste l'entier 42 entre parenthèses. Pour faire un tuple à un élément, il faut une virgule :(42,). - Vouloir modifier un tuple : si vous en avez besoin, c'est probablement une liste qu'il fallait choisir.
- Confondre
[ ]et( ): crochets = liste (modifiable), parenthèses = tuple (figé). Le sens du code change avec le délimiteur.
Vérification de compréhension
Quelle est la différence essentielle entre list et tuple ?