Listes et compréhensions de listes en Python, introduction à la notion de coût en temps
Les tableaux
Tableaux
En informatique, un tableau est une structure de données représentant une séquence finie d'éléments auxquels on peut accéder efficacement par leur position (ou indice), dans la séquence. C'est un type de conteneur que l'on retrouve dans un grand nombre de langages de programmation. On parle aussi de tableau indexé.
Dans les langages à typage statique (comme C, Java et OCaml), tous les éléments d'un tableau doivent être du même type. Certains langages à typage dynamique, tels que Python, permettent des tableaux hétérogènes (donc avec des données de natures différentes).
Les tableaux en Python
En Python, un tableau est représenté par un objet de type list
. Les principales différences entre les types list
et tuple
sont :
-
un objet de type
list
est une séquence entre crochets :>>> mon_tab = [45, 24, -35, -12] >>> type(mon_tab) <class 'list'>
-
un objet de type
list
est mutable, ce qui signifie qu'on peut changer sa valeur après sa création1, ce qui n'est pas le cas d'untuple
:>>> mon_tab = [45, 24, -35, -12] >>> mon_tab[2] = 1000 >>> mon_tab [45, 24, 1000, -12] >>> mon_tuple=(45, 24, -35, -12) >>> mon_tuple[2] = 1000 Traceback (most recent call last): File "<pyshell>", line 1, in <module> TypeError: 'tuple' object does not support item assignment
Les types list
et tuple
partagent sinon les mêmes propriétés : indices, accès aux éléments, longueur avec len()
, parcours séquentiel avec for
...
En particulier les algorithmes vus précédemment sont aussi valable pour un tableau.
Algorithme de recherche séquentiel
On veut construire une fonction chercheElement(elem, monTab)
qui renvoie :
- l'indice de la première occurrence de
elem
sielem
est présent dans le tableaumonTab
; - la longueur du tableau si l'élément
elem
n'est pas présent dans le tableaumonTab
.
Répondre aux questions suivantes :
- Décrire en pseudo-code un algorithme définissant cette fonction.
- Proposer une implémentation de ce pseudo-code en Python.
- Quel est le coût en temps de cet algorithme ? (à faire avec le professeur.)
A venir !
Méthode built-in index
en Python
La fonction précédente est déjà implémentée en Python, avec une différence : elle renvoie une erreur si l'élément cherché n'est pas dans le tableau.
>>> mon_tab = [45, 24, -35, -12, 24]
>>> mon_tab.index(24)
1
>>> mon_tab.index(36)
Traceback (most recent call last):
File "<pyshell>", line 1, in <module>
ValueError: 36 is not in list
Spécificité des listes en Python
Méthodes et utilisations des listes
-
Construire une liste vide :
>>> monTab = [ ] # ou bien >>> monTab = list()
-
Ajouter un élément à la fin d'une liste :
>>> monTab.append(3) >>> monTab [3] >>> monTab.append(5) >>> monTab.append(7) >>> monTab [3, 5, 7]
-
Supprimer et récupérer le dernier élément du tableau :
>>> dernier = monTab.pop() >>> dernier 7 >>> monTab [3, 5]
La méthode
pop
possède d'autres propriétés que je vous laisse rechercher. -
Convertir un tableau en tuple :
>>> monTuple = tuple(monTab) >>> monTuple (3, 5)
-
Convertir un tuple en tableau :
>>> monTab = list(monTuple) >>> monTab [3, 5]
-
Extraire des parties d'un tableau grâce aux slices :
>>> monTab = [35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47] >>> monTab[ :4] [35, 36, 37, 38] >>> monTab[7: ] [42, 43, 44, 45, 46, 47] >>> monTab[4:7] [39, 40, 41]
-
Concaténer des tableaux:
>>> [1, 2, 3] + [7, 8, 9] [1, 2, 3, 7, 8, 9]
Exercice
En utilisant les méthodes présentées ci-dessus :
-
Écrire une fonction
carre(n)
qui renvoie le tableau des carrés des nombres entiers compris entre \(0\) et \(n-1\).>>> carre(4) [0, 1, 4, 9]
-
Écrire une fonction
imagesf(deb,fin)
qui renvoie le tableau des images des nombres entiers compris entredeb
etfin
par la fonction \(f :x \mapsto 3x^2-2x+1\).>>> imagef(-2,3) [17, 6, 1, 2, 9, 22]
-
Écrire une fonction
genereListe(n)
qui renvoie un tableau de \(n\) nombres aléatoires compris entre \(1\) et \(n^2\). ( On pourra importer une fois le modulerandom
et utiliser la fonctionrandom.randint(a,b)
qui renvoie un nombre aléatoire entre \(a\) et \(b\) inclus). -
Ecrire une fonction
insere(monTab, val, i)
qui renvoie une liste dans laquelle est inseré l'élémentval
à l'indicei
au sein des éléments demonTab
, en supposant quei<len(monTab)
.>>> insere([1, 2, 3, 4],5,2) [1, 2, 5, 3, 4]
-
Écrire une fonction
compter(monTab,val)
permettant de compter le nombre d'occurrences deval
dansmonTab
.>>> compter([4, 6, 8, 6, 7, 6, 9], 6) 3 >>> compter([2, 4, 6],3) 0
-
Écrire une fonction
compterIndices(monTab,val)
permettant de renvoyer un tableau des indices des occurrences deval
dansmonTab
.>>> compter([4, 6, 8, 6, 7, 6, 9], 6) [1, 3, 5] >>> compter([2, 4, 6],3) []
-
Écrire une fonction
separer(monTab,val)
permettant, à partir d'une liste de nombresmonTab
d'obtenir deux listes. La première comporte les nombres inférieurs ou égaux à un nombre donné, la seconde les nombres qui lui sont strictement supérieurs :>>> separer([45, 21, 56 ,12, 1, 8, 30, 22, 6, 33], 30) [21, 12, 1, 8, 30, 22, 6], [45, 56, 33]
-
Écrire une fonction
plusProche(monTab,val)
permettant de rechercher la plus proche valeur d'un nombre dans une liste :>>> plusProche([45, 21, 56 ,12, 1, 8, 30, 22, 6, 33], 20) 21.
-
def carre(n) : t = [] for i in range(n+1) : t.append(i**2) return t
-
python def imagesf(deb,fin) : t =[] for i in range(deb, fin+1) : t.append(3*i**2 -2*i+1) return t
Construction de listes par compréhension
Jusqu'à présent nous avons défini nos listes par extension, c'est-à-dire en donnant exactement les éléments de la liste. Cependant, cette méthode n'est pas efficace pour de très grandes listes. Il faudra donc donner une méthode de construction de la liste, en essayant de comprendre les liens entre les différents éléments de cette liste. On parle alors de listes définies par compréhension.
Compréhensions de listes
Une des spécificités de Python est la capacité à construire des listes (et des tuples) par compréhension. Cette capacité est partagée avec d'autres langages, comme Haskell
.
premières compréhensions
-
Quel est le tableau associé à
monTab
?monTab = [4*nb for nb in range(100)]
-
Quel est le tableau associé à
monTab
? Pourquoi ?monTab = [3*nb for nb in range(100) if nb%2==0]
-
Quel est le tableau associé à
monTab
?monTab = [let for let in 'Abracadabra']
-
Quel est le tableau associé à
monTab
? Pourquoi ?monTab = [let for let in 'Abracadabra' if let.upper()!='A']
-
Quel est le tableau associé à
monTab
? Pourquoi ?monTab = [ord(let) for let in 'Abracadabra']
Réduire le code
Comme vous avez pu le constater, les compréhensions sont rapides à écrire. Et certaines fonctions de l'exercice n°2 peuvent être considérablement réduites : les fonctions carre
, imagef
et genereListe
.
Utilisez les compréhensions pour réduire leur taille.
A venir !