II. Approfondissement sur les listes▲
II-A. Les méthodes de la classe list▲
Voir More on Lists.
Méthode |
Action |
liste. |
Pour ajouter x à la fin de la liste liste. |
liste. |
Pour ajouter la liste liste2 à la suite de la liste liste. |
liste. |
Pour insérer l'élément x en position i dans liste. |
liste. |
Pour retirer et renvoyer le dernier élément dans liste. |
liste. |
Pour retirer et renvoyer l'élément en position i dans liste. |
liste. |
Pour retirer la première occurrence de x dans liste. |
liste. |
Renvoie la 1re position de x dans liste. Message d'erreur si aucune. |
liste. |
Renvoie le nombre d'occurrences de x dans liste. |
liste. |
Trie la liste par ordre croissant. |
liste. |
Renverse l'ordre des éléments de la liste. |
II-B. Saucissonnage ou slicing▲
>>>
liste =
['a'
, 'b'
, 'c'
, 'd'
, 'e'
, 'f'
, 'g'
, 'h'
, 'i'
]
>>>
liste1 =
liste[2
:5
] # tranche (slice) de la liste
>>>
print
liste1
['c'
, 'd'
, 'e'
]
L'instruction liste1 =
liste[2
:5
] crée une nouvelle liste liste1 dont les éléments sont ceux de liste allant de l'indice 2 (inclus : le 3e élément) à l'indice 5 (exclu : jusqu'au 5e élément, celui d'indice 4). On l'appelle une tranche (slice en anglais) de la liste.
Les indices entre crochets peuvent sortir de la plage d'indices de la liste :
>>>
liste2 =
liste[0
:100
] # tranche des indices de 0 à 100
>>>
print
liste2
['a'
, 'b'
, 'c'
, 'd'
, 'e'
, 'f'
, 'g'
, 'h'
, 'i'
]
Un troisième paramètre définit un pas :
>>>
liste3 =
liste[6
:2
:-
1
] # tranche des indices de 6 à 2 par pas de -1
>>>
print
liste3
['g'
, 'f'
, 'e'
, 'd'
]
Les ':' séparent les champs qui sont optionnels.
LISTE[indice départ (inclus) : indice arrivée (exclu) : pas]
Python crée la tranche en copiant l'élément de LISTE d'indice indice de départ, puis tous les éléments obtenus en ajoutant successivement pas à l'indice, tant qu'on ne dépasse pas indice d'arrivée. Par défaut : pas = 1.
- Si pas>0 : indice départ = 0 ; indice arrivée = len
(
LISTE) - Si pas<0 : indice départ = len
(
LISTE)-
1
; indice arrivée = -1
>>>
liste4 =
liste[::2
] # slicing par pas de 2
>>>
print
liste4
['a'
, 'c'
, 'e'
, 'g'
, 'i'
]
>>>
liste5 =
liste[::-
1
] # slicing par pas de -1
['i'
, 'h'
, 'g'
, 'f'
, 'e'
, 'd'
, 'c'
, 'b'
, 'a'
]
>>>
liste5 =
liste[3
::2
] # départ de l'indice 3, par pas de 2
>>>
print
liste5
['d'
, 'f'
, 'h'
]
>>>
liste6 =
liste[:3
:-
1
] # départ de la fin par pas de -1, arrêt avant l'indice 3
>>>
print
liste6
['i'
, 'h'
, 'g'
, 'f'
, 'e'
]
>>>
liste7 =
liste[:] # Pour copier une liste
>>>
print
liste7
['a'
, 'b'
, 'c'
, 'd'
, 'e'
, 'f'
, 'g'
, 'h'
, 'i'
]
II-C. Copie de liste▲
Il faut prendre garde à la façon dont Python copie une liste. Illustrons cela sur un exemple.
-
Copie d'une liste : jusqu'ici tout va bien.
Sélectionnez>>>
liste=
['a'
,'b'
,'c'
]# définition d'une liste
>>>
copie=
liste# puis copie de la liste
>>>
print
copie ['a'
,'b'
,'c'
] -
Modification d'un élément de la liste originelle. Tout se passe comme prévu.
Sélectionnez>>>
liste[0
]=
'modifié'
# Modifions un élément dans liste
>>>
print
liste ['modifié'
,'b'
,'c'
] - Mais, ô surprise, la copie aussi a été modifiée… contrairement à ce qu'on aurait pu attendre.
>>>
print
copie # regardons ce qu'est devenue la copie
['modifié'
, 'b'
, 'c'
]
Explication : en fait, une liste en Python ne contient que l'adresse mémoire où sont stockés ses éléments ; c'est ce que l'on appelle un pointeur.
Quand on copie liste dans copie, c'est cette adresse mémoire qui est copiée. C'est un alias qui est créé.
Quand on modifie un élément d'une liste, il est alors aussi modifié dans la copie. L'avantage étant qu'on encombre moins la mémoire centrale puisque les éléments de la liste ne figurent qu'en un seul emplacement mémoire.
Pour preuve, on peut utiliser la fonction intégrée id() qui retourne un entier long étant l'image de l'adresse mémoire où est stocké l'objet passé en argument. Les deux objets ont le même « identifiant ».
On peut contourner ce problème grâce à copie =
liste[:] qui fait une « copie superficielle » :
>>>
liste =
['a'
, 'b'
, 'c'
] # définition d'une liste
>>>
copie =
liste[:] # puis copie superficielle de la liste
>>>
print
copie
['a'
, 'b'
, 'c'
]
>>>
liste[0
] =
'modifié'
# Modifions un élément dans liste
>>>
print
liste
['modifié'
, 'b'
, 'c'
]
>>>
print
copie # regardons ce qu'est devenue la copie
['a'
, 'b'
, 'c'
]
Python fait une copie des éléments de la liste, mais c'est l'adresse mémoire des objets qui est copiée. Aussi, si l'un des éléments de la liste est aussi une liste, on retombe sur le même problème :
>>>
liste =
['a'
, 'b'
, [0
, 1
]] # définition d'une liste
>>>
copie =
liste[:] # puis copie superficielle de la liste
>>>
liste[0
] =
'modifié'
# Modifions un élément dans liste
>>>
liste[2
][0
] =
'MODIF'
# et un élément dans liste[2]
>>>
print
liste; print
copie # regardons ce qu'est devenue la copie
['modifié'
, 'b'
, ['MODIF'
,1
]]
['a'
, 'b'
, ['MODIF'
,1
]]
Pour contourner totalement le problème, utilisez la méthode liste.deepcopy
(
) du module standard copy qui effectue une « copie profonde »:
>>>
from
copy import
deepcopy
>>>
copie =
deepcopy
(
liste)
II-D. Listes définies par compréhension▲
On peut définir une liste à l'aide des mots-clés for
, in
et if
comme on définit un ensemble en mathématiques « en compréhension » :
[f
(
x) for
x in
liste] correspond à kitxmlcodeinlinelatexdvp\{ f(x) | x \in liste \}finkitxmlcodeinlinelatexdvp.
Exemple :
>>>
liste =
range(
10
) # définition de la liste des entiers de 0 à 9
>>>
liste_carres =
[x**
2
for
x in
liste] # liste des carrés des éléments de liste
>>>
print
liste_carres
[0
, 1
, 4
, 9
, 16
, 25
, 36
, 49
, 64
, 81
]
[f
(
x) for
x in
liste if
Condition
(
x)] correspond à kitxmlcodeinlinelatexdvp\{ f(x) | x \in liste\, \mathrm{tel\, que}\,Condition(x)\}finkitxmlcodeinlinelatexdvp.
Exemples :
>>>
liste =
[x**
2
for
x in
liste if
(
x %
2
==
0
)] # Carrés des éléments pairs
>>>
print
liste
[0
, 4
, 16
, 36
, 64
]
- Liste des multiples de 12 entre 0 et 100 :
>>>
liste =
[x for
x in
range(
101
) if
x %
12
==
0
] # Multiples de 12
>>>
print
liste
[0
, 12
, 24
, 36
, 48
, 60
, 72
, 84
, 96
]
- Liste des diviseurs d'un entier naturel n :
>>>
n =
120
>>>
diviseurs =
[x for
x in
range(
1
,n+
1
) if
(
n %
x ==
0
)] # Diviseurs de n
>>>
print
diviseurs
[1
, 2
, 3
, 4
, 5
, 6
, 8
, 10
, 12
, 15
, 20
, 24
, 30
, 40
, 60
, 120
]
On peut réécrire la méthode des trapèzes précédenteExemple 3 : calcul intégral - méthode des trapèzes en utilisant une liste en compréhension :