Tuple Favorite

En plus des listes, Python propose un autre type de structure de données : les tuples.

Un tuple ne peut pas être modifié après l'assignation car c'est un objet immuable.

C'est ce qui le différencie des listes.

Comment créer un tuple ?

Pour créer un tuple en Python, on utilise les parenthèses () puis on place les éléments à l'intérieur en les séparant par une virgule.

Comme les listes, les tuples peuvent contenir un nombre illimité d'éléments qui peuvent être de différents types.

Vous pouvez aussi stocker un tuple à l'intérieur d'un tuple :

t = ()  # Un tuple vide
print(t) # ()

t = ('spam', 'eggs') # Un tuple contenant deux strings
print(t)  # ('spam', 'eggs')

t = ('spam', 'eggs', 9, ['one', 'two', 'three'], True) # Un tuple avec des items de type différent
print(t)  # ('spam', 'eggs', 9, ['one', 'two', 'three'], True)

t = ('spam', 'eggs', (1, 2, 3), 9.4, True) # Un tuple contenant un autre tuple
print(t)  # ('spam', 'eggs', (1, 2, 3), 9.4, True)

Sachez que les parenthèses sont optionnelles ! Je vous conseille tout de même de les utiliser pour respecter la convention et parce que c'est aussi une bonne pratique 🙂

#norun
t = ('spam', 'eggs')
t2 = 'spam', 'eggs'

print(type(t))   # ('spam', 'eggs')
print(t)         # <class 'tuple'>

print(type(t2))  # ('spam', 'eggs')
print(t2)        # <class 'tuple'>

Pour créer un tuple qui ne contiendrait qu'un item, il faut faire suivre cet item d'une virgule pour indiquer à Python que c'est bien un tuple :

#norun
t = ('spam')
print(t)        # 'spam'
print(type(t))  # <class 'str'>

t = ('spam',)
print(t)        # ('spam')
print(type(t))  # <class 'tuple'>

Accéder à un élément

Comme pour les listes, il y a plusieurs façons d'accéder à un ou plusieurs items contenus dans un tuple.

Avec son indice

On peut utiliser les crochets [] pour accéder à un élément via son indice.

Comme pour toutes les structures de données en Python, le premier indice est 0.

Si vous avez un tuple qui contient trois éléments, l'indice du premier élément sera 0, celui du deuxième 1 et celui du troisième 2 :

t = ('spam', 'eggs')
print(t[0])  # 'spam'
print(t[1])  # 'eggs'

Même si les tuples se définissent avec des parenthèses (), il faut toujours utiliser les crochets [] pour accéder à un item grâce à son indice.

Si vous tentez d'utiliser un indice dont la valeur est supérieure à la longueur du tuple, vous déclencherez une erreur de type IndexError :

#norun
t = ('spam', 'eggs')
print(t[2])  # IndexError: tuple index out of range

L'indice que vous utilisez doit obligatoirement être un int sans quoi vous aurez le droit à une erreur de type TypeError :

#norun
t = ('spam', 'eggs')
print(t[1.0])  # TypeError: tuple indices must be integers or slices, not float

Avec un indice négatif

Vous pouvez aussi accéder à l'élément d'un tuple en utilisant un indice négatif ! C'est pratique lorsque vous avez un tuple qui contient beaucoup de valeurs et que vous avez besoin d'accéder aux dernières :

t = ('s', 'p', 'a', 'm')
print(t[-1])  # 'm'
print(t[-3])  # 'p'

Encore une fois, comme pour les listes, vous pouvez utiliser le slicing pour préciser un intervalle de recherche.

Pour rappel, la syntaxe pour le slicing est : [début:fin:pas]

t = ('d', 'o', 'c', 's', 't', 'r', 'i', 'n', 'g')

# Tous les items jusqu'à l'index 3
print(t[:3])    # ('d', 'o' 'c')

# Tous les items à partir de l'index 3 
print(t[3:])    # ('s', 't', 'r', 'i', 'n', 'g'

# Tous les items compris enter l'index 2 et l'index 6
print(t[2:6])   # ('c', 's', 't', 'r')

# Un item sur deux à partir de l'index 1 et jusqu'à la fin du tuple 
print(t[1::2])  # ('o', 's', 'r', 'n')

# Copie du tuple
print(t[:])     # ('d', 'o', 'c', 's', 't', 'r', 'i', 'n', 'g')

La valeur de début de l'intervalle est inclusive alors quelle celle de fin est exclusive !

Packing & Unpacking

Lorsque vous créez un tuple, en réalité vous assignez un pack de données à une variable.

De ce fait, vous pouvez aussi « déballer » ces données, c’est-à-dire déconstruire ce paquet pour récupérer chaque valeur contenue dans le tuple :

t = ('spam', 'eggs')
v1, v2 = t

print(v1)  # 'spam'
print(v2)  # 'eggs'

Quand vous faites ça, vous devez faire attention à ce qu'il y ait exactement le même nombre d'éléments d'un côté et de l'autre de l'assignation :

#norun
t = ('spam', 'eggs', 'knights')
v1, v2 = t          # ValueError: too many values to unpack (expected 2)
v1, v2, v3, v4 = t  # ValueError: not enough values to unpack (expected 4, got 3)

Cela fonctionne de la même façon avec ou sans les parenthèses !

C'est grâce à cette spécificité qu'on peut par exemple échanger les valeurs de deux variables sans passer par une variable temporaire :

a = 'spam'
b = 'eggs'

a, b = b, a

print(a) # 'eggs'
print(b) # 'spam'

Modifier un tuple

Vous le savez, les tuples sont des objets immuables.

Cependant, vous pouvez quand même modifier les objets muables stockés à l'intérieur d'un tuple comme les listes, les dictionnaires, etc.

#norun
t = ('spam', 'eggs', [1, 2, 3], 'knights')
t[0] = 'lumberjack'  # TypeError: 'tuple' object does not support item assignment
t[2][0] = 9          # ('spam', 'eggs', [9, 2, 3], 'knights')

Vous pouvez également concaténer deux tuples à l'aide de l'opérateur plus + :

t1 = ('spam', 'eggs')
t2 = ('knights', 'lumberjack')

print(t1 + t2)  # ('spam', 'eggs', 'knights', 'lumberjack')

Supprimer un tuple

Vous ne pouvez pas supprimer un élément en particulier d'un tuple car les tuples sont des objets immuables.

Par contre, vous pouvez supprimer le tuple en entier grâce à l'instruction del :

#norun
t = ('spam', 'eggs', 'knights', 'lumberjack')

del t[0]  # TypeError: 'tuple' object doesn't support item deletion
del t
print(t)  # NameError: name 't' is not defined

Les deux seules méthodes disponibles avec les tuples

Étant des objets immuables, les méthodes sur les tuples sont peu nombreuses : il n'y en a que deux !

Récupérer le nombre d'occurrences dans un tuple avec count() :

t = ('spam', 'eggs', 'knights', 'lumberjack')
print(t.count('knights'))  # 1

t = ('a', 'b', 'b', 'c', 'b', 'a', 'c', 'b')
print(t.count('b'))        # 4

Récupérer l'indice d'une valeur dans un tuple avec index() :

t = ('spam', 'eggs', 'knights', 'lumberjack')
print(t.index('spam'))     # 0
print(t.index('knights'))  # 2

Les avantages des tuples par rapport aux listes

  • Les tuples étant immuables, il est plus rapide d'itérer sur un tuple que sur une liste.
  • Si les données stockées ne sont pas destinées à être modifiées tout au long de la vie du programme, utilisez un tuple.
  • Comme les tuples sont immuables, ils peuvent être utilisés comme clé dans un dictionnaire (une autre structure de donnée possible en Python) ce qui n'est pas le cas des listes.