
Si on demande à Python l'élément numéro cinquante d'une liste qui n'en compte que dix, il se passe quelque chose de particulier. La question m'a tenue éveillée plus longtemps que je ne l'admets, un soir où mon vieux laptop trônait sur la table en formica, une tisane refroidissant à côté du clavier et un cahier de brouillon couvert de flèches à moitié illisibles. Je suis débutante, toujours en auto-formation sur Python, une liste de courses à la fois, et cette histoire de slicing — la manière de découper des morceaux de liste sans y toucher vraiment — a fini par me faire douter de tout ce que je croyais savoir sur les listes.
Le slicing ne plante pas si on dépasse le bout de la liste
Python, contrairement à ce que je pensais au début, ne panique pas du tout si on lui demande plus que ce qu'une liste contient — du moins pas avec le slicing. Essayez ma_liste[2:50] sur une liste de dix éléments à peine et il ne se passe rien de dramatique : vous récupérez simplement tout ce qui existe à partir de l'indice 2, jusqu'au bout, sans un seul message d'erreur. C'est là que la confusion s'installe pour beaucoup de gens qui débutent : on associe presque toujours "dépasser les limites" à un plantage, parce que c'est exactement ce qui arrive avec l'accès direct à un indice. Demandez ma_liste[50] sur cette même liste et Python vous renvoie une erreur bien nette, un message qui pointe clairement l'indice fautif — ce genre de retour, je l'ai fini par apprécier, tant il est plus simple à décoder qu'un écran qui reste muet.
Le slicing, lui, se contente de vous donner ce qu'il trouve, sans clause de contrôle, sans exception, sans rien. Je trouve ça presque déroutant, comme si on demandait douze parts d'une tarte qui n'en a que huit et qu'on recevait poliment les huit parts sans qu'on nous fasse la remarque. Pas de drame, pas de gêne, juste le silence poli d'un ordinateur qui fait ce qu'il peut avec ce qu'il a.

L'indice de fin ne compte jamais pour un élément inclus.
Une autre idée reçue traîne autour du slicing : que le deuxième chiffre entre crochets désigne le dernier élément qu'on va récupérer. Ce n'est pas vrai, et ça m'a fait perdre un temps que je préfère ne pas chiffrer avant de l'accepter. Avec ma_liste[1:4], on obtient les éléments aux indices 1, 2 et 3 — trois éléments, pas quatre — parce que la borne de fin sert de limite qu'on n'atteint jamais tout à fait, un peu comme quand on partage un plat de famille en se disant qu'on s'arrête juste avant la dernière part pour la laisser à quelqu'un d'autre. C'est un calcul de soustraction tout bête, 4 moins 1, qui m'a d'ailleurs aidée à mieux apprendre les opérateurs mathématiques en python, même si je reste modeste sur le sujet.
Le même principe s'applique aux chaînes de caractères, ce qui m'a étonnée la première fois : découper un mot avec [0:3] fonctionne exactement pareil que sur une liste, caractère après caractère plutôt qu'élément après élément. Et pour ne pas avoir à retaper ces indices à chaque fois, j'ai fini par ranger la logique dans une petite fonction plutôt que de copier-coller le même bout de code d'un script à l'autre — une habitude que j'ai adoptée après avoir trop souvent recyclé des extraits trouvés en ligne sans vraiment comprendre pourquoi ils marchaient, ce qui m'a valu quelques mauvaises surprises.

Le piège du slicing qui modifie tout en silence
Ce troisième mythe est peut-être le plus retors : croire que découper une liste avec les deux points est toujours une opération sans risque, juste une façon de lire ce qu'il y a dedans. Ce n'est vrai que si on ne touche à rien. Le jour où j'ai voulu supprimer un morceau avec ma_liste[1:3] = [], ça a marché — mais ça a aussi modifié la liste d'origine directement, sans prévenir, et j'ai mis un moment à comprendre pourquoi une variable ailleurs dans mon code affichait soudain des valeurs qui n'avaient plus de sens.
Depuis, je préfère assigner le résultat d'un découpage à une nouvelle variable plutôt que de charcuter la liste de départ, histoire de garder une version propre sous la main si jamais je me suis trompée quelque part.

Inverser une liste sans y penser à deux fois
Reste le pas, ce troisième chiffre qu'on peut ajouter après les deux points et qui décide si on avance case par case ou si on en saute. Avec [::2], un élément sur deux disparaît du résultat, et avec [::-1], toute la liste se retrouve inversée d'un coup, sans boucle, sans variable intermédiaire, sans rien d'autre qu'une syntaxe qu'on croirait sortie d'un tour de magie bon marché — le genre de petit truc que je ressors volontiers quand je m'amuse à utiliser le module random en python pour bricoler des mini-jeux les soirs où j'ai un peu plus d'énergie.
Ma première boucle for écrite sans regarder mes notes a fonctionné du premier coup, un soir où je ne m'y attendais pas du tout, et je m'en souviens précisément parce que c'est resté rare — alors le pas négatif, qui fait en une ligne posée entre crochets ce qu'une boucle entière ferait avec plus d'efforts, a de quoi impressionner quand on vient de là.
Valérian, mon collègue de bureau, m'a envoyé un mème sur les erreurs "off-by-one" l'autre jour, un truc qu'il ne comprend visiblement pas lui-même mais qui m'a fait rire au moment où j'en avais besoin — preuve que même sans coder une seule ligne, tout le monde connaît la sensation d'être décalé d'une case.
Théophane, un lecteur qui commente souvent depuis Lyon, m'a écrit récemment qu'il butait justement sur ces histoires d'indices et de bornes, alors qu'il a une sacrée avance sur moi sur d'autres points du langage — comme quoi personne n'avance dans le même ordre. La règle que je garde maintenant, celle qui m'évite de reperdre une soirée entière : le slicing ne plante jamais, il rend juste ce qu'il peut avec les bornes qu'on lui donne, et c'est l'indexation directe avec un seul chiffre entre crochets qu'il faut surveiller si on veut un vrai message d'erreur. Avant de repartir marcher un peu du côté de la place de Jaude pour aérer la tête, j'ai relu mes trois lignes de découpe une dernière fois, satisfaite, pour une fois, de savoir exactement pourquoi elles ne planteraient pas.