09 - Slicing
Introduction
Le slicing (ou « tranchage ») est une technique fondamentale de Python qui permet d’extraire une sous-séquence à partir d’une séquence (liste, chaîne de caractères, tuple). C’est l’un des outils les plus puissants et les plus élégants du langage.
Imaginez une baguette de pain : le slicing revient à en couper une tranche entre deux positions. Vous choisissez où commencer, où finir, et éventuellement vous ne prenez qu’une rondelle sur deux.
Rappel : indexation
Avant de découper, rappelons comment Python numérote les éléments d’une séquence. Considérons la liste :
L = ['a', 'b', 'c', 'd', 'e', 'f']
Les indices positifs commencent à 0 et les indices négatifs comptent à partir de la fin :
Éléments : a b c d e f
Indices + : 0 1 2 3 4 5
Indices - : -6 -5 -4 -3 -2 -1
Ainsi L[0] vaut 'a', L[3] vaut 'd', L[-1] vaut 'f' et L[-2] vaut 'e'.
Syntaxe du slicing
La syntaxe générale est :
L[début:fin:pas]
où :
débutest l’indice du premier élément sélectionné (inclus) ;finest l’indice de fin (exclu, comme pourrange()) ;pasest l’écart entre deux indices successifs (par défaut1).
Le résultat est toujours une nouvelle séquence du même type.
Analogie avec les intervalles mathématiques : le slicing L[i:j] correspond à l’intervalle \([i\,;\, j[\), c’est-à-dire que la borne de fin n’est jamais incluse.
Exemples de base
L = ['a', 'b', 'c', 'd', 'e', 'f']
print(L[1:4]) # ['b', 'c', 'd'] — indices 1, 2, 3
print(L[0:3]) # ['a', 'b', 'c'] — les 3 premiers
print(L[2:5]) # ['c', 'd', 'e'] — indices 2, 3, 4
Visualisons le premier exemple :
Éléments : a b c d e f
Indices : 0 1 2 3 4 5
^---------^
début=1 fin=4 (exclu)
Résultat : ['b', 'c', 'd']
Valeurs par défaut
On peut omettre un, deux ou les trois paramètres :
L = ['a', 'b', 'c', 'd', 'e', 'f']
print(L[:3]) # ['a', 'b', 'c'] — début omis → commence à 0
print(L[3:]) # ['d', 'e', 'f'] — fin omise → va jusqu'à la fin
print(L[:]) # ['a', 'b', 'c', 'd', 'e', 'f'] — copie complète
print(L[::2]) # ['a', 'c', 'e'] — un élément sur deux
Règle générale :
- si
débutest omis, il vaut0(début de la séquence) ; - si
finest omise, elle vautlen(L)(fin de la séquence) ; - si
pasest omis, il vaut1.
Slicing avec des indices négatifs
Les indices négatifs fonctionnent aussi dans le slicing :
L = ['a', 'b', 'c', 'd', 'e', 'f']
print(L[:-1]) # ['a', 'b', 'c', 'd', 'e'] — tout sauf le dernier
print(L[-3:]) # ['d', 'e', 'f'] — les 3 derniers
print(L[-4:-1]) # ['c', 'd', 'e'] — du 4e avant la fin au dernier (exclu)
print(L[1:-1]) # ['b', 'c', 'd', 'e'] — sans le premier ni le dernier
Slicing avec un pas
Le troisième paramètre permet de sauter des éléments :
L = ['a', 'b', 'c', 'd', 'e', 'f']
print(L[::2]) # ['a', 'c', 'e'] — un sur deux, en partant du début
print(L[1::2]) # ['b', 'd', 'f'] — un sur deux, en partant de l'indice 1
print(L[::3]) # ['a', 'd'] — un sur trois
Pas négatif : parcours en sens inverse
Avec un pas négatif, Python parcourt la séquence de droite à gauche :
L = ['a', 'b', 'c', 'd', 'e', 'f']
print(L[::-1]) # ['f', 'e', 'd', 'c', 'b', 'a'] — liste inversée
print(L[::-2]) # ['f', 'd', 'b'] — un sur deux, en sens inverse
print(L[4:1:-1]) # ['e', 'd', 'c'] — de l'indice 4 à l'indice 2 (1 exclu)
Valeurs par défaut avec un pas négatif :
- si
débutest omis, il vaut-1(dernier élément) ; - si
finest omise, elle vaut au-delà du premier élément (c’est-à-dire que tout est pris).
Attention : slicing vs indexation
L[1] et L[1:2] ne renvoient pas la même chose :
L = ['a', 'b', 'c', 'd', 'e', 'f']
a = L[1] # 'b' — un élément (type str)
b = L[1:2] # ['b'] — une liste à un élément (type list)
print(type(a), a) # <class 'str'> b
print(type(b), b) # <class 'list'> ['b']
L’indexation renvoie l’élément lui-même, le slicing renvoie une nouvelle séquence.
Slicing sur les chaînes de caractères
Le slicing fonctionne exactement de la même manière sur les chaînes :
mot = "informatique"
print(mot[:5]) # 'infor'
print(mot[5:]) # 'matique'
print(mot[::2]) # 'ifraiu'
print(mot[::-1]) # 'euqitamrofni' — chaîne inversée
Modification par slicing (listes uniquement)
Sur une liste (séquence muable), le slicing peut être utilisé pour remplacer une portion :
L = ['a', 'b', 'c', 'd', 'e', 'f']
L[2:4] = ['X', 'Y', 'Z']
print(L) # ['a', 'b', 'X', 'Y', 'Z', 'e', 'f']
On a remplacé deux éléments ('c' et 'd') par trois éléments. La taille de la liste change.
Attention : cela ne fonctionne pas sur les chaînes de caractères (qui sont immutables).
Résumé
| Expression | Signification |
|---|---|
L[i:j] | Éléments de l’indice i à j-1 |
L[:j] | Les j premiers éléments |
L[i:] | Du i-ème à la fin |
L[:] | Copie complète |
L[::k] | Un élément sur k |
L[::-1] | Séquence inversée |
L[i:j:k] | De i à j-1, par pas de k |