C'est l'un des pièges! de python, qui peuvent échapper à des débutants.
L' words[:]
, c'est la magie de la sauce ici.
Observer:
>>> words = ['cat', 'window', 'defenestrate']
>>> words2 = words[:]
>>> words2.insert(0, 'hello')
>>> words2
['hello', 'cat', 'window', 'defenestrate']
>>> words
['cat', 'window', 'defenestrate']
Et maintenant, sans l' [:]
:
>>> words = ['cat', 'window', 'defenestrate']
>>> words2 = words
>>> words2.insert(0, 'hello')
>>> words2
['hello', 'cat', 'window', 'defenestrate']
>>> words
['hello', 'cat', 'window', 'defenestrate']
La principale chose à noter ici est que l' words[:]
renvoie un copy
de la liste existante, de sorte que vous êtes une itération sur une copie, qui n'est pas modifié.
Vous pouvez vérifier si vous êtes en se référant aux mêmes listes à l'aide de id()
:
Dans le premier cas:
>>> words2 = words[:]
>>> id(words2)
4360026736
>>> id(words)
4360188992
>>> words2 is words
False
Dans le second cas:
>>> id(words2)
4360188992
>>> id(words)
4360188992
>>> words2 is words
True
Il est intéressant de noter que, [i:j]
est appelé le découpage de l'opérateur, et ce qu'il fait c'est qu'elle renvoie une nouvelle copie de la liste, en commençant à partir de l'index i
, jusqu'à (mais pas y compris index) j
.
Donc, words[0:2]
vous donne
>>> words[0:2]
['hello', 'cat']
En omettant l'indice de départ signifie la valeur par défaut est 0
, tout en omettant le dernier indice signifie que la valeur par défaut est len(words)
, et le résultat final est que vous recevez une copie de l' ensemble de la liste.
Si vous voulez faire de votre code un peu plus lisible, je vous recommande l' copy
module.
from copy import copy
words = ['cat', 'window', 'defenestrate']
for w in copy(words):
if len(w) > 6:
words.insert(0, w)
print(words)
Cela se fait de la même chose que votre premier extrait de code, et est beaucoup plus lisible.
Sinon (comme mentionné par le DSM dans les commentaires) et sur python >=3, vous pouvez également utiliser words.copy()
qui fait la même chose.