Licence CC BY-NC-ND, Thierry Parmentelat & Arnaud Legout
from IPython.display import HTML
HTML(filename="_static/style.html")
containers (1/2)#
plusieurs types pratiques et efficaces sont fournis de base, et notamment
liste et tuple: ce notebook
dictionnaire, ensemble: un peu plus tard
la liste#
permet de créer une liste de n’importe quels objets
les listes sont dynamiques, de taille variable
une liste peut être hétérogène (avoir des composants de types différents)
peuvent être imbriquées
comme une liste est un objet, on peut avoir une liste de listes
ou y mettre d’autres containers
bref, c’est super malléable et hyper pratique
toutefois, pas toujours hyper-efficace
basique#
L = []
L = [4, 'bob', 10 + 1j, True]
# on peut mélanger les types
L
[4, 'bob', (10+1j), True]
# les indices en python
# commencent à 0
L[2]
(10+1j)
modification par index#
# les indices commencent à 0
L
[4, 'bob', (10+1j), True]
# pour modifier un élément précis
L[2] = "BOOM"
# pas besoin de préserver les types
# ni rien de ce genre
L
[4, 'bob', 'BOOM', True]
modification par slice#
liste = [1, 2, 4, 8, 16, 32]
# le slicing est disponible
# sur les listes
liste[2:]
[4, 8, 16, 32]
# on peut aussi modifier
# toute une slice
liste[2:4] = [10, 20, 30]
liste
[1, 2, 10, 20, 30, 16, 32]
attention#
L[i] = L2remplace le i-ème élément de
Lpar la listeL2
L[i:j] = L2insère tous les éléments de la liste
L2à la positioniaprès avoir supprimé les éléments
ijusqu’àj-1dansL
modification sous pythontutor#
liste = [1, 2, 4, 8, 16, 32]
liste
[1, 2, 4, 8, 16, 32]
liste[2:4] = [10, 20, 30]
liste
[1, 2, 10, 20, 30, 16, 32]
liste[3] = [100, 200]
liste
[1, 2, 10, [100, 200], 30, 16, 32]
%load_ext ipythontutor
%%ipythontutor curInstr=1 width=1000
liste = [1, 2, 4, 8, 16, 32]
liste[2:4] = [10, 20, 30]
liste[3] = [100, 200]
.append() et .pop()#
les méthodes sur les listes
sont plutôt optimisées pour les ajouts à la fin de la liste
les deux méthodes les plus couramment utilisées sont
.apppend()et.pop()
L = []
for i in range(4):
L.append(i)
L
[0, 1, 2, 3]
while L:
print(L.pop())
3
2
1
0
ajouter des deux cotés ?
si vous avez besoin de massivement insérer aussi en début de liste, alors envisagez la liste doublement chainée
from collections import deque
deque?
ajouts et tris#
des méthodes qui mutent la liste (modifications in-place)
L.extend(L2)ajoute chaque élément deL2à la fin deLL.insert(i, x)ajoute x à la positioniL.sort()trieLL.reverse()renverse les éléments deL
retraits#
toujours des modifications en place:
L.pop(i)pour supprimer à un endroit précisL.remove(x)supprime la première occurrence dexdansL
s’il n’y a pas dex, une exception est retournéedel L[i]supprime le i-ème élémentdel L[i:j]
del L[i:j:k]supprime tous les éléments de la slice
et plein d’autres…
en réalité il y a une foultitude de méthodes disponibles sur les listes, on ne signale ici que l’essentiel
entrainez-vous à retrouver la page de la doc qui vous les décrit, en googlant python builtin types
qui devrait vous amener rapidement à
https://docs.python.org/3/library/stdtypes.html
et notammment cette section: https://docs.python.org/3/library/stdtypes.html#mutable-sequence-types
digression: range()#
range()est une fonction native (en anglais builtin)qui retourne un objet itérable
c’est-à-dire sur lequel on peut faire un
foron y reviendra longuement
for i in range(4):
print(i, end=" ")
0 1 2 3
c’est quoi ce end=” “ ?
le paramètre end=" " indique à print de ne pas ajouter de fin de ligne,
mais plutôt un espace, à la fin de l’impression
les paramètres de range()#
essentiellement, même logique que le slicing
range(j)balaie de0àj-1range(i, j)balaie deiàj-1range(i, j, k)balaie deiàj-1par pas dekpour obtenir une liste on transforme (cast) en liste en appelant
list()
for i in range(1, 21, 5):
print(i, end=" ")
1 6 11 16
list(range(1, 21, 5))
[1, 6, 11, 16]
exemples de listes#
# la fonction list() permet
# de convertir en liste
L = list(range(5))
L
[0, 1, 2, 3, 4]
# un par un
L.append(100)
# ou plusieurs à la fois
L.extend([10, 20])
L
[0, 1, 2, 3, 4, 100, 10, 20]
# très souvent utilisé
# rappel: optimisé pour ça
L.pop()
L
[0, 1, 2, 3, 4, 100, 10]
# pour trier c'est simple
# on va creuser ça tout de suite
L.sort()
L
[0, 1, 2, 3, 4, 10, 100]
tri sur les listes#
le tri des listes est très puissant en Python
tri en place méthode
list.sort()
il y a aussi la fonction built-in
sorted()
qui trie toutes les séquences
et retourne une nouvelle liste
L = [10, -5, 3, 100]
# tri en place: attention cela retourne None !
this_is_none = L.sort()
# par contre L est modifiée
L
[-5, 3, 10, 100]
L1 = [10, -5, 3, 100]
# crée une copie
L2 = sorted(L1)
# voyez
print(L1)
print(L2)
[10, -5, 3, 100]
[-5, 3, 10, 100]
attention au retour de L.sort()
dans le premier exemple, le retour de la méthode sort est None; cela pour bien manifester le fait qu’il n’y a pas eu de copie
tri et renversement de liste#
pour conclure - temporairement - sur ce sujet:
on peut aussi trier selon un critère ad hoc
on en reparlera plus tardon retrouve la même dualité pour le renversement
L.reverse()renverse la liste en place (et retourneNone)
reversed(L)retourne une copie renversée
avertissements à propos des listes#
(1) les itérateurs sont plus forts#
la liste est un outil très très pratique
mais parfois (souvent) pas nécessaire
car nécessite de la mémoire
alors qu’on a souvent seulement besoin d’itérer sur le contenu
dans ce cas, on a recours a des techniques plus adaptées : itérateurs et autres générateurs
sujet avancé que l’on verra plus tard
exercice de pensée
vous devez calculer la somme des carrés des n premiers entiers
pour cela le fait de construire d’abord une liste avec tous ces entiers est inutile et contreproductif,
car cela signifie allouer tout un tas de mémoire dont on n’a pas besoin !
c’est pourquoi range() ne renvoie pas une liste mais un itérateur
mais on reparlera longuement de tout ça
(2) pas efficace pour calcul scientifique#
le coté flexible en taille et en type rend la liste très pratique
mais attention ça peut devenir très inefficace
notamment pour le calcul scientifique
pas d’équivalent parmi les types Python natifs d’un bon vieux tableau C/C++/Fortran
penser absolument aux tableaux
numpypour ce type d’application !
le tuple#
comme des listes, mais immutables
syntaxe:
()au lieu de[]
# syntaxe pour un tuple vide
T = ()
T
()
# syntaxe pour un singleton
T1 = (4,)
# ou encore
T2 = 4,
T1 == T2
True
c’est la virgule qui fait le tuple
attention: c’est la virgule qui est importante, on peut omettre les () - la plupart du temps
(4)est un entier, et(4,)est un tuple
basique#
# syntaxe pour plusieurs éléments
T1 = (3, 5, 'alice', 10+1j)
# ou encore
T2 = 3, 5, 'alice', 10+1j
# ou encore
T3 = 3, 5, 'alice', 10+1j,
T1 == T2
True
T1 == T3
True
le tuple est non mutable#
un tuple est non mutable
les fonctions faisant des modifications in-place
ne s’appliquent donc pas aux tuples
# Python n'est pas content
try:
T1[3] = 5
except Exception as e:
print("OOPS", e)
OOPS 'tuple' object does not support item assignment
pourquoi le tuple ?#
à ce stade, vous vous demandez sans doute:
pourquoi créer un tuple ?
si c’est juste moins puissant que la liste ?la réponse est liée aux tables de hachage
(dictionnaires et ensembles)
que l’on va voir un peu plus tard
un peu de patience donc…