[Plan du site]
Vous êtes ici ---
> Le Site du Zéro
> Les tutoriels
> Non-Officiels
> Programmation
> Python
> Apprenons Python ! > Le début, la base de tout... > Les listes - Des valeurs qui en contiennent d'autres
> Lecture du tutoriel
Les listes - Des valeurs qui en contiennent d'autres
Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Nous avons maintenant un niveau de programmation qui nous permet de traiter quelques problèmes simples. Pourtant, nous ne savons toujours pas manipuler des ensembles de données. Par exemple, vous serez amenés tôt ou tard à traiter des cas où le nombre de variables vous est inconnu. Comment ferez vous alors ?
De même que dans l'exemple du chapitre sur les boucles, vous ne pouviez pas écrire une infinité de print, ici il est impossible d'utiliser une infinité de variables : ça n'est pas une façon souple de procéder.
Heureusement, Python met à notre disposition un type baptisé "list", qui permet de créer des listes de données (ce qui semble normal

). Elles nous permettront de traiter des données diverses - à condition naturellement que nous apprenions à les utiliser

. Les listes, en Python, sont un petit peu différentes de celles que vous rencontrerez dans d'autres langages. C'est lié au fait qu'à la base, Python était un langage de script. Il possède donc des objets haut niveau très souples, mais qui ne correspondent pas forcément à la vision théorique habituelle de ces objets.
Ce sont donc des objets très riches, sur lesquels nous devrons revenir afin de savoir les utiliser à la mesure de leur puissance. Mais pourtant, avec les rudiments que nous allons apprendre dans ce chapitre, nous pourrons déjà résoudre beaucoup de nouveaux problèmes
Si vous vous rappelez bien de ce que nous avons vu, les chaînes de caractère étaient capables de stocker tout et n'importe quoi... tant que nous transformions ce tout et n'importe quoi en caractères. Cela nous permettait de stocker des données, mais pas avec une très grande efficacité. Il existe donc des façons de faire plus adaptées, utilisant des types plus puissants.
La liste est un de ces types. En Python, une liste peut stocker n'importe quelle valeur, et une même liste peut contenir des valeurs de types différents.
Nous nous représenterons donc les listes comme des boîtes contenant des valeurs
ordonnées, c'est à dire que ces valeurs suivent un ordre : il y'a une première valeur, qui en précède une deuxième, etc - cela dit, les listes ne sont pas
triées, c'est à dire qu'un 3 peut venir avant un 2, par exemple.
Python nous permet de nous représenter les listes simplement, comme une suite de valeurs mises entre crochets, et séparées par des virgules. Par exemple, pour la liste composée des valeurs 1, 2 et 3, nous notons
[1,2,3].
Les listes sont capables de contenir toute valeur que nous avons déjà rencontrée, sans en changer le type (un entier reste un entier, une chaîne reste une chaîne, etc.). Nous pouvons donc par exemple directement faire des calculs avec les éléments de ces listes. Mais comment accéder à ces éléments ? Je suis sûr que vous avez une petite idée, si en tout cas vous repensez à ce que nous faisions pour les chaînes de caractères.
Gagné. Il suffit d'écrire, à côté de la liste,
l'index, entre crochets de l'élément auquel vous souhaitez accéder, de même que pour les chaînes. Petite démonstration :
Code : Python1
2
3
4
5 | >>> maListe = [1, 2, 3]
>>> maListe[0]
1
>>> type(maListe[0])
<type 'int'>
|
Ici encore, le premier élément porte le numéro 0. Contrairement à ce qui se serait passé avec une chaîne de caractères, nous constatons que l'élément renvoyé reste un nombre, et pas un caractère. Si nous avions créé une chaîne
"123", nous aurions récupéré le caractère
"1". Les listes sont donc des
structures de données plus appropriées que les chaînes pour la manipulation de groupes de données, dans nos programmes.
Pourtant, les chaînes ont leur utilité pour stocker des éléments. Nous les réutiliserons notamment lorsque nous manipulerons des fichiers, dans un futur proche

. Mais à l'intérieur de nos programmes, les listes sont beaucoup plus souples d'utilisation.
En tout cas, vous devinez que l'on peut plus facilement réaliser des calculs avec les éléments d'une liste. Nous allons nous entraîner en écrivant le code d'une fonction qui prend en paramètre une liste de taille variable, et qui en calcule la moyenne. Rappelons que pour calculer la valeur moyenne d'une série de nombres, nous additionnons ces nombres, et nous divisons la somme obtenue par la longueur de la liste. À ce stade de notre réflexion, nous devons nous poser deux questions : comment parcourir une liste ? Et comment calculer ensuite sa longueur ?
Il serait plus adapté de se poser les questions dans l'autre sens. En fait, la longueur d'une liste se calcule exactement comme celle d'une chaîne, avec la fonction
len. Et là, nous trouvons la réponse à la première de nos deux questions : il faut utiliser
while bien sûr - c'est un réflexe que vous auriez du acquérir depuis que nous connaissons les chaînes

.
Commençons par écrire le code qui calcule la somme des éléments d'une liste que nous appelons liste. Il nous suffit de parcourir toute la liste (de 0 à
len(liste)) en additionnant à chaque fois les éléments que nous rencontrons (dans une variable qui servira à accumuler les calculs). Outre cet accumulateur, vous savez déjà qu'il nous faudra un compteur et la longueur de la liste, exactement comme pour les chaînes :
Code : Python1
2
3
4
5
6
7 | liste = [1, 5, 2, 34] # Une liste de test
compteur = 0
longueur = len(liste)
accumulateur = 0
while compteur < longueur:
accumulateur += liste[compteur]
compteur += 1
|
Cela se fait plutôt simplement. Nous pouvons de même écrire le code qui calcule la moyenne d'une liste : il nous suffit de rajouter à la fin l'opération
accumulateur/longueur. Nous pouvons donc définir deux nouvelles fonctions, somme et moyenne, prenant toutes les deux une liste en argument. Cette fois-ci, nous n'utilisons plus de liste de test. Commençons par
Code : Python1
2
3
4
5
6
7
8 | def somme(uneListe):
compteur = 0
longueur = len(liste)
accumulateur = 0
while compteur < longueur:
accumulateur += liste[compteur]
compteur +=1
return accumulateur
|
L'indentation limite le
while. Lorsqu'il est fini, le
return (appartenant encore à la fonction puisqu'il est sur la même ligne d'indentation) renvoie l'accumulateur dans lequel nous avons faits nos calculs.
En réalité, Python laisse déjà à notre disposition une fonction nommée
sum, calculant la somme des éléments d'une liste. Par exemple
sum([3,65,-4]) renverra 64. Mais il ne fournit aucune fonction calculant la moyenne - nous allons la définir :
Code : Python1
2 | def moyenne(uneListe):
return sum(uneListe)/len(uneListe)
|
Cette définition est très courte, puisqu'elle fait appel à deux autres fonctions. Vous notez que l'on n'utilise pas de variable - à quoi cela servirait-il ? Le code est un petit peu dense pour nous, humbles débutants, mais parfaitement lisible.
Jusqu'à maintenant, nous n'avons utilisé que des listes contenant des nombres entiers. Pourtant, les listes en Python sont des structures de données capables de contenir tous les types :
[1,45.6,"jambon beurre"] est une liste valide. Cela présente a priori un avantage, la souplesse. En effet, la fonction
sum, par exemple, supporte aussi bien les listes contenant des nombres entiers que des nombres à virgule, voire les deux :
sum([15, 12.5, -4.3]) est parfaitement valide.
Ainsi, quand nous serons bien plus avancés que maintenant, nous pourrons manipuler des listes contenant des données qui supportent des opérations en commun, comme ici les entiers (type
int) et les nombres à virgule (type
float). Nous pouvons par exemple utiliser le code suivant :
Code : Python1
2
3
4
5
6
7
8 | listeCompliquee= ["barbecue", [1,2,3,4,5], "zoo"]
def sommeDesLongueurs(uneListe):
compteur, accumulateur = 0, 0
longueur = len(uneListe)
while compteur < longueur:
accumulateur += len(uneListe[compteur]) # On accumule la longueur des éléments de la liste
compteur += 1
return accumulateur
|
Dans cet exemple, bien que les éléments de listeCompliquee soient de types différents, ils peuvent tous être utilisés avec
len. Si on avait écrit
sommeDesLongueurs(listeCompliquee), on aurait eu le résultat 16. Cependant, en écrivant
autreListe = [[1,2,3,4,5], 42, "hello"] puis
sommeDesLongueurs(autreListe), on aurait eu une erreur.
En effet, cette nouvelle liste contient un entier, 42, et len ne peut pas être appliquée à un entier. C'est pour cela qu'il faudra faire très attention lorsque vous manipulerez des données de plusieurs types à la fois : si vous utilisez des opérations particulières et que vos listes contiennent des données qui ne supportent pas ces opérations, c'est le drame

.
Python ne détecte pas ces erreurs avant l'exécution. Vous pouvez donc, avec un peu de malchance, écrire des programmes qui fonctionneront très bien chez vous quand vous les testerez, et planteront chez d'autres personnes à cause d'une bête erreur de typage. On dit que Python possède un typage
dynamique : il donne des types aux données qu'il manipule pendant l'exécution du programme. Si cela vous intéresse, je vous invite à consulter
le tutoriel de bluestorm sur le typage.
Nous avons remarqué des points communs entre les chaînes de caractères, que nous créons avec
str, et les listes. Tout d'abord, toutes deux sont des ensembles contenant d'autres valeurs, même si ce ne sont que des caractères (appartenant également à
str) dans le cas des chaînes. Ensuite, toutes les deux sont ordonnées : un premier élément vient avant un second, etc. Ces deux types possèdent donc une longueur, qui peut être obtenue avec
len.
On dit que les listes et les chaînes de caractères sont des séquences. Les séquences ne sont pas un vrai type de données, en Python, mais on utilise quand même le concept pour parler des opérations qu'elles supportent.
Ces opérations sont par exemple le calcul de leur longueur, l'accès à leurs éléments (qui sont placés dans un certain ordre, nous verrons des séquences qui ne sont pas ordonnées, ou des structures de données ordonnées qui ne sont pas des séquences), le fait de pouvoir être séparées en plusieurs morceaux (ce que l'on verra dans quelques chapitres), le fait d'être parcourues (pour le moment avec une boucle
while)...
Ce ne sont que des exemples. Nous en découvrirons bien plus. Pour l'instant, vous devez comprendre que Python, qui est (au moins à la base) un langage de script, permet de manipuler simplement des données complexes, pour simplifier la vie du programmeur. Vous devez aussi comprendre que Python, qui est un langage moderne, demande des connaissances que nous n'avons pas encore. Aussi, si nous ne savons pas encore faire beaucoup de choses avec les listes, ça n'est qu'une question de temps, puisque nous ré-expliquerons des choses à leur sujet dans au moins deux chapitres futurs

.
Revenons sur la capacité des séquences à être parcourues. Jusqu'à présent, comme dans le chapitre sur les chaînes ou celui-ci, nous avons utilisé des boucles
while. Il est temps de découvrir une nouvelle boucle : la boucle
for, qui s'utilise conjointement au mot clef
in. Son principe est
précisément de parcourir une séquence en formant une boucle - elle va donc nous simplifier grandement la vie

. Si vous avez déjà utilisé d'autres langages de programmation, comme C# ou PHP, vous reconnaîtrez la boucle
foreach. Il ne faut en revanche pas la confondre avec la boucle
for-each de Scheme, ni avec les boucles
for qu'on retrouve en C, C++, PHP, JavaScript, BASIC... bien qu'on puisse l'utiliser pour les mêmes choses.
La syntaxe de la boucle
for est très simple :
Code : Python1 | for uneValeur in plusieursValeurs
|
En fait, la boucle
for va simplement parcourir élément par élément la séquence
plusieursValeurs, en créant une variable
uneValeur qui prendra successivement la valeur de chaque élément de la séquence

. Cette variable sera utilisable après dans le corps de la boucle. Reprenons un exemple utilisé dans le
chapitre sur les boucles :
Code : Python1
2
3
4
5
6
7
8
9 | maChaine = "Les chaussettes de l'archi-duchesse sont-elles sèches et archisèches"
compteur = 0
nombreCar = 0
longueurChaine = len(maChaine)
while compteur < longueurChaine:
if maChaine[compteur] == "s": # Si on a bien trouvé le caractère cherché (ici 's')
nombreCar += 1
compteur += 1
print "On a trouvé", nombreCar,"fois le caractère s"
|
Pour que vous puissiez bien comprendre ce que nous apporte
for, voici la nouvelle version :
Code : Python1
2
3
4
5 | nombreCar = 0
for caractere in maChaine:
if caractere == "s":
nombreCar += 1
print "On a trouvé", nombreCar,"fois le caractère s"
|
Notre code en est grandement simplifié

. Tout ce qui pouvait servir à nous repérer dans la chaîne, comme par exemple
longueurChaine, ou bien le
compteur, etc. a disparu.
Si nous décomposons l'action de la boucle, nous voyons qu'au premier tour on stocke un premier caractère de
maChaine dans la variable
caractere, puis qu'au deuxième on stocke le suivant, et ainsi de suite. Après, le corps de la boucle est normalement exécuté, avec à l'intérieur la variable
caractere, qui est dite
locale (bien que Python, ainsi que certains autres langages, permettent sa réutilisation à l'extérieur de la boucle, c'est déconseillé - les versions futures de Python empêcheront d'ailleurs cette pratique).
Nous pouvons écrire un autre exemple, qui affiche tous les éléments d'une liste (un par ligne) :
Code : Python1
2
3 | uneListe = [1, 2, 3]
for elem in uneListe:
print elem
|
Si une liste contient une autre séquence, celle-ci ne sera pas parcourue. Par exemple, reprenez l'exemple précédent avec
listeCompliquee = ["barbecue", [1,2,3,4,5], "zoo"]. En exécutant la boucle
for, nous aurons
Code : Console | barbecue
[1, 2, 3, 4, 5]
zoo |
Alors que nous aurions pu écrire :
Code : Python1
2
3 | for sequence in listeCompliquee:
for elem in sequence:
print elem
|
qui cette fois-ci parcourt tous les éléments de toutes les séquences de
listeCompliquee. Essayez d'écrire la version avec des boucles
while et des compteurs : plus compliqué n'est-ce pas

?
Comme le laisse supposer le titre de cette partie, le mot clef
in peut être utilisé seul. Il donne alors la possibilité de vérifier qu'une séquence contient ou non un élément, et s'utilise de façon assez naturelle. C'est un opérateur, de même que
== ou
>, c'est à dire qu'il se place entre l'élément (placé à gauche) et la séquence (à droite).
Il sert aussi bien sur les chaînes de caractères que sur les éléments d'une liste. On peut également l'utiliser pour vérifier qu'une chaîne est comprise dans une autre. Voici quelques exemples :
Code : Python 1
2
3
4
5
6
7
8
9
10
11
12 | >>> "b" in "abc"
True # Le caractère b est bien compris dans la chaîne
>>> "bd" in "abcde"
False # En revanche, même si b et d sont compris dans la chaîne "abcde", la chaîne "bd" ne s'y trouve pas :)
>>> "bd" in ["ab", "bc", "bd", "ae"]
True # Ici la chaîne est un élément de la liste
>>> 3 in [1, 2, 3]
True # Idem, le chiffre 3 se trouve bien dans la liste
>>> [1, 2] in [1, 2, 3]
False # Peut-être que vous vous attendiez à ce que cette ligne vérifie que [1, 2, 3] contient bien 1 et 2, mais non...
>>> [1, 2] in [[2, 3], [3, 4], [1, 2]]
True # Elle vérifiait que la liste [1, 2] s'y trouvait (ce qui est le cas ici)
|
Rien de compliqué, donc

.
Nous avons dit plus haut que cette boucle
for pouvait se rapprocher de la boucle
for du C (et d'autres langages), ou du moins de son utilisation habituelle, comme "boucle ayant un compteur de tour intégré". Dans ces langages, il est fréquent de voir cette boucle utilisée pour faire parcourir à une variable une succession de valeurs numériques, par exemple de 1 à 10, en incrémentant à chaque fois une variable d'un pas de 1. On peut naturellement choisir d'autres pas, certains négatifs.
Puisque la boucle
for de Python parcourt une séquence, on pourrait l'utiliser pour imiter celle du C. Il suffirait, par exemple, pour aller de 1 à 10, d'écrire
Code : Python1 | for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
|
cependant cela deviendrait vite lassant, et surtout cela ne nous permettrait pas de parcourir un nombre de valeur décidé par l'utilisateur (puisque cette méthode implique d'utiliser une liste fixe). Bref, vous l'aurez compris, il existe une fonction en Python qui s'occupe de générer cette liste pour nous : la fonction range.
Son utilisation est très simple : si vous lui passez un paramètre n, elle générera une liste de 0 à (n - 1). Par exemple,
range(5) nous donnera la liste
[0, 1, 2, 3, 4]. Il suffit donc d'écrire
Code : Python1
2 | for i in range(5):
print i
|
pour avoir un programme qui comptera pour nous jusqu'à 4.
Mais si vous souhaitez commencer à 1, il est tout à fait possible de le préciser. La fonction range peut prendre deux arguments a et n, pour générer une liste de a à (n - 1). On peut donc obtenir
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] en écrivant
range(1, 11).
Enfin, il est possible de préciser le pas séparant chaque valeur en passant un troisième argument, comme dans l'exemple suivant :
Code : Python1
2
3 | for i in range(10, 0, -1):
print str(i) + "..."
print "Décollage !"
|
Naturellement, vous pouvez passer à range des variables plutôt que des valeurs constantes.
Il est temps de commencer à parler des choses sérieuses : ici nous allons aborder la mutabilité des listes

. Derrière ce terme barbare se cache une propriété intéressante des listes : on peut les modifier, modifier ce qu'elles contiennent, sans pour autant les reconstruire (en les réaffectant avec le symbole
= donc).
Pour l'instant, nous n'avons utilisé les listes que pour les présenter. Nous apprendrons à vraiment les utiliser comme moyen efficace de stocker nos données dans le chapitre suivant, qui abordera un côté de Python dont nous n'avons pour le moment pas parlé.
Nous ne savons donc manipuler que des listes qui existent "déjà", c'est à dire que nous n'en créons pas de nouvelles comme on pourrait le faire, par exemple, avec les valeurs que saisirait un utilisateur - nous utilisons des listes que nous écrivons entièrement dans notre programme. Cependant, la mutabilité nous permet de modifier ces listes, sans en créer d'autres.
Pour accéder à un élément d'une liste
nombres ayant l'index
i, nous écrivons
nombres[i]. La mutabilité des listes autorise à modifier ce même élément tout simplement en écrivant :
Code : Python1 | nombres[i] = nouvelle_valeur
|
Nous pouvons donc utiliser notre connaissance pour modifier des listes déjà existantes. Par exemple, nous allons doubler tous les éléments d'une liste, en les y re-stockant à chaque fois. Notez que, comme nous avons besoin de modifier la liste, nous sommes obligés d'utiliser un
for sur autre chose que ses éléments (ici, nous utilisons la boucle
for pour générer les indices) :
Code : Python1
2
3 | nombres = [1, 2, 3, 4]
for i in range(len(nombres)):
nombres[i] = 2 * nombres[i] # L'élément de nombres ayant l'index i est doublé
|
Vous pouvez tout comprendre : la première ligne crée une liste toute bête, stockée dans une variable nombres. La seconde peut être lue comme "De 0 jusqu'à la longueur de nombres" (cela concerne donc tous les éléments de nombres), et la troisième "Nous doublons l'élément de nombres et nous le replaçons au même endroit de nombres".
Nous pouvons naturellement définir une fonction qui fait ça à notre place, comme celle qui suit. Le code est le même, à part que l'on traite une liste nombres passée cette fois-ci en argument, et que l'on est obligé de la retourner à la fin :
Code : Python1
2
3
4 | def double(L):
for i in range(len(L)):
L[i] *= 2
return L
|
Nous pouvons alors tester notre jolie fonction dans la ligne de commande Python :
Code : Console | >>> nombres = [1, 2, 3, 4]
>>> double(nombres)
[2, 4, 6, 8] # Valeur de retour normale et prévisible
>>> nombres # Mais, attendez une minute...
[2, 4, 6, 8] # La liste a été doublée o_O |
Le début est tout à fait normal, puisque nous définissons une liste
nombres, que nous passons ensuite à la fonction
double. Nous obtenons donc sa valeur de retour, c'est à dire la liste doublée. Cependant, lorsque nous demandons à Python d'afficher le contenu de
nombres, toute la liste a été modifiée. Jusqu'à présent, nous ne connaissions pas ce comportement. En effet, à chaque fois que nous passions une variable à une fonction, celle-ci pouvait retourner une nouvelle valeur, mais pas modifier l'ancienne. Exemple :
Code : Console | >>> def double(x):
... x = 2 * x
... return x
...
>>> x = 4
>>> double(x)
8
>>> x # x conserve sa valeur normale
4 |
Dans le cas de cette dernière fonction, vous devez bien comprendre que nous modifions
x à
l'intérieur du corps de la fonction. Nous pouvons nous représenter les variables Python comme des laisses que nous attachons autour des valeurs, et qui nous servent à nous les rappeler après (la comparaison est un peu brutale, mais c'est comme si vous tiriez sur la laisse de votre chien pour qu'il revienne

). En suivant cette comparaison, nous comprenons que lorsque nous exécutons
x = quelque_chose, cela signifie qu'une variable
x est attachée à une valeur
quelque_chose dans ce que nous appellerons le
contexte de la fonction : ça n'est plus une valeur appartenant à l'ensemble du programme que contient
x, mais une valeur qui est calculée dans la fonction, qui appartient à la fonction - l'utilisation du symbole
= donne donc à
x une nouvelle valeur. On dit que x est une variable
locale à la fonction.
En revanche, pour la fonction
double qui prenait une liste en argument, nous utilisions bien un symbole
=, mais pas seulement : en fait, c'est sur un élément de la liste que nous l'utilisons. Un peu dur hein

? Lorsque vous faites
nombres[i] =, la valeur sur laquelle pointe
nombres est inchangée, cela reste la même liste - mais vous remplacez un de ses éléments par un autre ! C'est en fait comme si vous pouviez modifier la variable x locale à une fonction, en continuant d'y accéder après.
Le contenu de la liste est donc modifiable ; on dit que la liste est
mutable. Nous verrons qu'il y'a d'autres façon de modifier les listes sans les affecter de nouveau, et nous verrons d'autres valeurs en Python qui sont également mutables. Par opposition, les valeurs telles que les entiers, les flottants, les booléens ou les chaînes de caractères (comme nous allons le voir) sont dites
immutables : vous ne pouvez pas les modifier, vous pouvez seulement en créer de nouvelles avec une nouvelle affectation de la variable qui les contient.
En effet, essayons de changer un élément d'une chaîne :
Code : Console | >>> maChaine = "foo"
>>> maChaine[0] = "b"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment |
Nous verrons plus tard que Python offre de nombreux mécanismes beaucoup plus intéressants et puissants pour manipuler les séquences que cette fonction double que nous avons créée. Nous verrons aussi que les cas dans lesquels nous modifions nos listes à l'intérieur même des fonctions sont plutôt rares, mais que c'est une caractéristique du langage qu'il faut savoir exploiter.
- Les listes sont des valeurs pouvant en contenir d'autres, quels que soient leurs types (y compris d'autres listes). Elles appartiennent au type list, se délimitent par des crochets.
- Les listes, comme les chaînes de caractères, sont des séquences : elles ont un ordre, contiennent des éléments, et ont une longueur. Si la longueur est 0, c'est que l'on est en présence d'une liste vide [].
- Les séquences se parcourent à l'aide de for...in, comme dans :
Code : Python1
2 | for element in sequence:
code utilisant element...
|
- L'opérateur in peut aussi s'utiliser seul pour tester l'appartenance d'un élément à une séquence.
- La fonction range permet de générer des listes de nombres ; si on ne lui passe qu'un paramètre n, elle génère une liste de nombres de 0 à (n - 1) ; si on lui en passe 2, elle génère une liste de nombres du premier paramètre jusqu'au nombre avant le deuxième ; si on lui passe un troisième paramètre, ce dernier sert comme pas séparant chaque valeur de la liste de retour.
- Les listes sont mutables : leurs éléments peuvent changer de valeur et elles peuvent être modifiées à l'intérieur d'une fonction sans pour autant qu'on ai besoin de retourner une nouvelle valeur.
Beaucoup d'exercices classiques, pour vous faire manipuler les listes

.
- Créez une fonction affiche qui... affiche les éléments d'une liste un par un, mais sur une même ligne (à la fin, revenez à la ligne). Utilisez pour cela une particularité de l'instruction print
.
- Créez une fonction max et une fonction min qui prennent toutes les deux en argument une liste, et en renvoie respectivement le plus grand et le plus petit élément.
- Ecrivez une fonction max2 qui renvoie cette fois-ci le deuxième plus grand élément d'une liste. N'oubliez pas de traiter le cas où tous les éléments de la liste sont égaux (dans ce cas, la fonction renvoie arbitrairement -1. Nous verrons plus tard dans le cours comment gérer proprement les erreurs). Pensez également au cas où le plus grand élément de la liste est au tout début.
- Reprenez le code de la fonction double, et modifiez-le pour qu'elle prenne désormais en argument le nombre par lequel on souhaite multiplier les éléments de la liste. Si ce nombre est 0, retournez une liste vide. Appelez cette nouvelle fonction "multiplie"
.
- Utilisez la fonction multiplie pour écrire une fonction table, qui affiche (sans la renvoyer, à l'aide d'un print) une table de multiplication sur plusieurs lignes. Par exemple, table(4) devrait afficher les 10 premiers multiples de 1, puis les 10 premiers multiples de 2, puis de 3 et enfin de 4.
- Créez une fonction qui renvoie le premier indice du maximum de la liste. Appelez-la min_indice. Créez maintenant une fonction qui renvoie le dernier indice du maximum de la liste. Appelez-la max_indice. Enfin, créez une fonction qui renvoie une liste de deux éléments, le premier et le dernier indice. Est-il raisonnable d'utiliser les deux fonctions définies avant ?
- Créez une fonction qui prend deux listes en argument, et trouve le nombre d'éléments communs que ces deux listes possèdent. Nous ne corrigerons pas cet exercice, demandez de l'aide sur le forum du site si vous n'y arrivez pas - plusieurs façons de faire peuvent être déployées, comparons les
.
La plupart des exercices étaient accessibles. Si vous n'avez pas réussi à en résoudre la moitié, reprenez tranquillement le chapitre

.
Secret (cliquez pour afficher)Pour afficher tous les éléments d'une liste sur une même ligne, il suffit de finir la ligne de l'instruction print par une virgule : les éléments seront alignés

. Le print isolé à la fin permet de finir la ligne.
Code : Python1
2
3
4 | def affiche(liste):
for e in liste:
print e,
print
|
Secret (cliquez pour afficher)Voici la fonction max :
Code : Python1
2
3
4
5
6 | def max(liste):
le_max = liste[0]
for element in liste:
if element > le_max:
le_max = element
return le_max
|
On stocke le maximum dans une variable nommée le_max, dont la première valeur est le premier élément de la liste. En effet, on pourrait mettre 0, mais si tous les éléments de la liste étaient négatifs, le résultat serait faux

.
Secret (cliquez pour afficher) Plus difficile, cette fonction max2 est un bon exercice de réflexion

.
Code : Python 1
2
3
4
5
6
7
8
9
10
11
12 | def max2(liste):
maxa = maxb = liste[0]
for element in liste:
if element > maxa:
maxb = maxa # "L'ancien" maximum devient le deuxième maximum
maxa = element # et on stocke le nouveau
elif (element > maxb and element != maxa) or ((maxa == maxb) and (element != maxb)):
maxb = element
if maxa == maxb:
return -1
else:
return maxb
|
La condition du milieu est composée : on a un nouveau deuxième maximum
- si element est plus grand que le deuxième maximum que l'on avait avant (sans être égal à maxa)
- ou si maxa et maxb étaient égaux (si le plus grand élément était au début de la liste, alors il faut que l'on en prenne un nouveau)
Secret (cliquez pour afficher)Pas de grande difficulté pour cette fonction...
Code : Python1
2
3
4
5
6 | def multiplie(liste, n):
if n == 0:
return []
for i in range(len(liste)):
liste[i] *= n
return liste
|
Secret (cliquez pour afficher)En réutilisant les fonctions affiche et multiplie, notre code est très simple !
Code : Python1
2
3 | def table(n):
for i in range(1, n+1):
affiche(multiplie(range(10), i))
|
Secret (cliquez pour afficher) On pourrait écrire une fonction qui commence par rechercher le maximum de la liste (ou réutiliser max comme avant), mais il faudrait alors rechercher une nouvelle fois l'indice - on ferait ainsi plus d'un tour de liste, ce qui est plus coûteux que cette solution tout-en-un

.
Code : Python1
2
3
4
5
6
7
8 | def min_indice(liste):
m = liste[0]
j = 0
for i in range(len(liste)):
if liste[i] > m:
j = i
m = liste[i]
return j
|
Pour la deuxième fonction, le code est pratiquement le même, mais on rajoute un elif afin de tester si l'on retrouve le maximum plus loin dans la liste : dans ce cas, c'est ce nouvel indice qu'il nous faut !
Code : Python 1
2
3
4
5
6
7
8
9
10 | def max_indice(liste):
m = liste[0]
j = 0
for i in range(len(liste)):
if liste[i] > m:
j = i
m = liste[i]
elif liste[i] == m:
j = i
return j
|
Ecrivez maintenant le code qui renvoie les deux indices. Est-ce qu'il vaut mieux écrire
Code : Python1
2 | def indices(liste):
return [min_indice(liste), max_indice(liste)]
|
ou bien refaire une fonction qui ne réalise qu'un seul tour de boucle ? D'après ce que nous avons dit plus haut, la réécriture semble une meilleure idée

.
Ce chapitre marque la fin de la partie I. La partie II devrait être légèrement plus technique, assurez-vous donc d'avoir compris tous ces points fondamentaux

.