Les réponses ci-dessus ne traitent pas de l'affectation des tranches. Pour comprendre l'affectation des tranches, il est utile d'ajouter un autre concept à l'art ASCII :
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
Slice position: 0 1 2 3 4 5 6
Index position: 0 1 2 3 4 5
>>> p = ['P','y','t','h','o','n']
# Why the two sets of numbers:
# indexing gives items, not lists
>>> p[0]
'P'
>>> p[5]
'n'
# Slicing gives lists
>>> p[0:1]
['P']
>>> p[0:2]
['P','y']
Une heuristique consiste, pour une tranche de zéro à n, à penser : "zéro est le début, commencez au début et prenez n éléments dans une liste".
>>> p[5] # the last of six items, indexed from zero
'n'
>>> p[0:5] # does NOT include the last item!
['P','y','t','h','o']
>>> p[0:6] # not p[0:5]!!!
['P','y','t','h','o','n']
Une autre heuristique est la suivante : "pour n'importe quelle tranche, remplacez le début par zéro, appliquez l'heuristique précédente pour obtenir la fin de la liste, puis comptez le premier nombre en remontant pour enlever des éléments du début".
>>> p[0:4] # Start at the beginning and count out 4 items
['P','y','t','h']
>>> p[1:4] # Take one item off the front
['y','t','h']
>>> p[2:4] # Take two items off the front
['t','h']
# etc.
La première règle de l'affectation des tranches est que, puisque le découpage en tranches renvoie à une liste, une affectation de tranche nécessite une liste (ou autre itérable) :
>>> p[2:3]
['t']
>>> p[2:3] = ['T']
>>> p
['P','y','T','h','o','n']
>>> p[2:3] = 't'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only assign an iterable
La deuxième règle de l'affectation de tranche, que vous pouvez également voir ci-dessus, est que quelle que soit la portion de la liste renvoyée par l'indexation de tranche, c'est la même portion qui est modifiée par l'affectation de tranche :
>>> p[2:4]
['T','h']
>>> p[2:4] = ['t','r']
>>> p
['P','y','t','r','o','n']
La troisième règle de l'assignation de tranche est que la liste assignée (itérable) ne doit pas nécessairement avoir la même longueur ; la tranche indexée est simplement découpée et remplacée en masse par ce qui est assigné :
>>> p = ['P','y','t','h','o','n'] # Start over
>>> p[2:4] = ['s','p','a','m']
>>> p
['P','y','s','p','a','m','o','n']
La partie la plus délicate à laquelle il faut s'habituer est l'affectation à des tranches vides. En utilisant les heuristiques 1 et 2, il est facile de s'y retrouver. indexation une tranche vide :
>>> p = ['P','y','t','h','o','n']
>>> p[0:4]
['P','y','t','h']
>>> p[1:4]
['y','t','h']
>>> p[2:4]
['t','h']
>>> p[3:4]
['h']
>>> p[4:4]
[]
Et une fois que vous avez vu cela, l'affectation de la tranche à la tranche vide a également du sens :
>>> p = ['P','y','t','h','o','n']
>>> p[2:4] = ['x','y'] # Assigned list is same length as slice
>>> p
['P','y','x','y','o','n'] # Result is same length
>>> p = ['P','y','t','h','o','n']
>>> p[3:4] = ['x','y'] # Assigned list is longer than slice
>>> p
['P','y','t','x','y','o','n'] # The result is longer
>>> p = ['P','y','t','h','o','n']
>>> p[4:4] = ['x','y']
>>> p
['P','y','t','h','x','y','o','n'] # The result is longer still
Notez que, puisque nous ne changeons pas le deuxième numéro de la tranche (4), les éléments insérés s'empilent toujours contre le "o", même lorsque nous assignons à la tranche vide. La position pour l'affectation à la tranche vide est donc l'extension logique des positions pour les affectations aux tranches non vides.
En revenant un peu en arrière, que se passe-t-il si l'on poursuit notre procession de comptage du début de la tranche ?
>>> p = ['P','y','t','h','o','n']
>>> p[0:4]
['P','y','t','h']
>>> p[1:4]
['y','t','h']
>>> p[2:4]
['t','h']
>>> p[3:4]
['h']
>>> p[4:4]
[]
>>> p[5:4]
[]
>>> p[6:4]
[]
Avec le découpage en tranches, une fois que vous avez terminé, vous avez terminé ; il ne commence pas à découper en tranches à l'envers. En Python, vous n'obtenez pas de strides négatifs, sauf si vous le demandez explicitement en utilisant un nombre négatif.
>>> p[5:3:-1]
['n','o']
Il y a des conséquences bizarres à la règle "une fois qu'on a fini, on a fini" :
>>> p[4:4]
[]
>>> p[5:4]
[]
>>> p[6:4]
[]
>>> p[6]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
En fait, comparé à l'indexation, le découpage Python est bizarrement à l'abri des erreurs :
>>> p[100:200]
[]
>>> p[int(2e99):int(1e99)]
[]
Cela peut parfois s'avérer utile, mais cela peut aussi conduire à un comportement quelque peu étrange :
>>> p
['P', 'y', 't', 'h', 'o', 'n']
>>> p[int(2e99):int(1e99)] = ['p','o','w','e','r']
>>> p
['P', 'y', 't', 'h', 'o', 'n', 'p', 'o', 'w', 'e', 'r']
En fonction de votre demande, cela pourrait... ou ne pourrait pas... être ce que vous espériez là !
Vous trouverez ci-dessous le texte de ma réponse initiale. Elle a été utile à de nombreuses personnes, je ne voulais donc pas la supprimer.
>>> r=[1,2,3,4]
>>> r[1:1]
[]
>>> r[1:1]=[9,8]
>>> r
[1, 9, 8, 2, 3, 4]
>>> r[1:1]=['blah']
>>> r
[1, 'blah', 9, 8, 2, 3, 4]
Cela peut également clarifier la différence entre le découpage et l'indexation.