IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Programmation Python pour les scientifiques

Listes et autres structures de données - Cours avec exercices corrigés


précédentsommairesuivant

I. Les listes en Python

I-A. Présentation

Dès que l'on commence à manipuler en Python un grand nombre de données, l'usage de variables devient insuffisant. Exemple : imaginons que l'on veuille stocker les notes des élèves d'une classe pour calculer leur moyenne et leur écart-type. On peut imaginer d'utiliser N variables de type float (N étant le nombre d'élèves de la classe), puis d'écrire des fonctions moyenne() et ecart_type() prenant N paramètres ; fastidieux lorsque N=47, et il faudra la réécrire pour chaque nouvel effectif…

 
Sélectionnez
def moyenne47(n1, n2, ..., n47) :
    return (n1 + n2 + ... + n47) / 47.0

En Python, la structure de données qui va nous aider est la liste. C'est un objet de type list qui permet de collecter des éléments : données de type quelconque : int, float, str, bool, d'autres listes, etc.

Exemple :

 
Sélectionnez
>>> liste = [1, 2, 3, 'toto']
 
Sélectionnez
>>> print liste 
[1, 2, 3, 'toto']
 
Sélectionnez
>>> type(liste) 
<type 'list'>
 
Sélectionnez
>>> len(liste) 
4
 
Sélectionnez
>>> liste[0], liste[1], liste[len(liste) - 1] 
(1, 2, 'toto')

Une liste est créée à l'aide d'une affectation. Ses éléments sont entre crochets []. La fonction len() prend en argument une liste et retourne son nombre d'éléments. Les éléments d'une liste s'obtiennent grâce à leur indice entre crochets. Attention, le premier élément a pour indice 0 !

Exemple : reprenons notre problème de calcul de la moyenne des notes. Mettons à profit ce que nous avons vu sur les listes ainsi que la fonction sum() qui prend en argument une liste et retourne, lorsque c'est possible, le résultat de l'opération '+' sur ses éléments.

Saisissons la liste des notes :

 
Sélectionnez
>>> liste_notes = [10, 12, 14, 6, 8, 15, 3, 17]   # la liste de notes

Définition de la fonction moyenne() qui s'applique à toute liste non vide de nombres :

 
Sélectionnez
>>> def moyenne(liste) : # fonction moyenne()
        return sum(liste) / float(len(liste))
 
Sélectionnez
>>> moyenne(liste_notes)
 10.625

On obtient le résultat attendu, la moyenne est de 10,625. Sans la conversion en float d'un des arguments de la division, le résultat retourné aurait été 10 (quotient de la division entière) sous Python 2 (mais pas sous Python 3).

Les listes sont des objets modifiables (on dit aussi mutables) : on peut modifier leurs éléments.

 
Sélectionnez
>>> liste = [1, 2, 3, 'toto'] # une liste
 
Sélectionnez
>>> liste[0] = 'le début'
>>> liste[2] = [-1, -2, -3]
>>> print liste 
['le début', 2, [-1,- 2, -3], 'toto']
 
Sélectionnez
>>> print liste[-1], liste[-2]
'toto' [-1, -2, -3]
>>> print liste[-5], liste[4]
 
Sélectionnez
IndexError: list index out of range

On modifie un élément de la liste en lui affectant une nouvelle valeur (de n'importe quel type, simple ou complexe). L'indice -1 permet d'obtenir le dernier élément. C'est plus simple que liste[len(liste) - 1]. L'indice -2 permet d'obtenir l'avant-dernier élément, etc. Un indice qui n'est pas compris entre -len(liste) et len(liste)-1 produit une erreur IndexError.

 
Sélectionnez
>>> print liste 
['le début', 2, [-1,- 2, -3], 'toto']
 
Sélectionnez
>>> type(liste[0]), type(liste[1]), type(liste[2]) 
(<type 'str'>, <type 'int'>, <type 'list'>
 
Sélectionnez
>>> print liste[2][0] # liste[2] est une liste 
-1

Les éléments d'une liste sont des valeurs de différents types, celles qu'on lui a affectées.

Une liste de listes permet de constituer un tableau bi-dimensionnel.

 
Sélectionnez
>>> l=[['a', 'b'], ['c', 'd']] 
>>> print l[0][0], l[0][1], l[1][0], l[1][1] 
a b c d

I-B. La fonction range

Avec un argument entier n, range(n) retourne la liste des n premiers entiers.

 
Sélectionnez
>>> print range(10) 
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Avec deux arguments entiers m, n, range(m,n) retourne la liste des max(0, n−m) entiers consécutifs qui sont compris entre m (inclus) et n (exclu).

 
Sélectionnez
>>> print range(0,10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print range(-1,11)
[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10]

Avec trois arguments entiers m, k, n, range(m, n, k) retourne la liste des entiers de la forme kitxmlcodeinlinelatexdvpm+k \cdot pfinkitxmlcodeinlinelatexdvp, avec p entier naturel, et qui sont compris entre m (inclus) et n (exclu).

 
Sélectionnez
>>> print range(0, 10, 2)
[0, 2, 4, 6, 8]
>>> print range(10,0,-2)
[10, 8, 6, 4, 2]

Un argument non entier provoque un message d'erreur TypeError.

I-C. La boucle for

L'instruction for permet de répéter une séquence d'instructions, en boucle, pour une variable qui décrit une liste d'éléments.

for variable in list:

On l'écrit en langage algorithmique :

 
Sélectionnez
Pour tout i dans liste faire : 
     Instruction 1
     ...
     Instruction N

Bien sûr la variable i peut apparaître dans le bloc d'instructions (comme variable locale : c'est une « copie », la modifier n'affecte pas la liste).

 
Sélectionnez
for i in liste : 
    # instruction 1
    # ...
    # instruction N

produit un résultat identique à la boucle while :

 
Sélectionnez
L = len(liste)    # L est la longueur de la liste
j = 0             # j est l'indice
while (j < L) :   # tant que l'indice ne dépasse pas 
    i=liste[j]    # i est l'élément d'indice j
    # instruction 1
    # ...
    # instruction N
    j = j + 1     # incrémenter l'indice j

Une boucle while est plus générale. On a le droit de modifier la longueur de la liste dans la boucle while ; on n'en a pas le droit dans la boucle for (on peut toujours modifier les éléments de la liste). Dans une boucle for, le nombre de répétitions de la boucle est fixée à l'entrée dans la boucle, ici c'est len(liste).

I-D. Exemples

I-D-1. Exemple 1 : liste des carrés

Nous souhaiterions créer la liste des carrés des entiers compris entre 0 et 20. Pour cela, on utilisera la méthode list.append() appliquée aux objets de type liste qui permet d'ajouter un élément en queue de liste :

 
Sélectionnez
>>> liste_vide=[ ]
>>> liste_vide.append('toto')
>>> print liste_vide
['toto']
>>> liste_vide.append('le héros') 
>>> print liste_vide
['toto', 'le héros']

Solution : cliquez sur l'icône Image non disponible.

Liste des carrés
Cacher/Afficher le codeSélectionnez
 
Sélectionnez
>>> print liste_carres
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400]

I-D-2. Exemple 2 : la suite de Fibonacci

Écrire une fonction fibonacci() qui prend en argument un entier N et retourne une liste contenant les N premiers termes de la suite de Fibonacci : kitxmlcodeinlinelatexdvpu_0 =0, \,u_1 =1, \, \forall n \in\mathbb{N}\quad \, u_{n+2}=u_{n+1}+u_nfinkitxmlcodeinlinelatexdvp.

Solution : cliquez sur l'icône Image non disponible.

Fibonacci
Cacher/Afficher le codeSélectionnez

La définition de la fonction est proche de la définition par récurrence de la suite, la boucle for jouant le rôle de la relation de récurrence.

 
Sélectionnez
>>> fibonacci(16)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

I-D-3. Exemple 3 : calcul intégral - méthode des trapèzes

Soit l'application kitxmlcodeinlinelatexdvpf\,:\,x\mapsto x^2finkitxmlcodeinlinelatexdvp définie sur kitxmlcodeinlinelatexdvp\mathbb{R}^2finkitxmlcodeinlinelatexdvp.

Écrire une fonction trapeze() qui prend en argument deux réels kitxmlcodeinlinelatexdvpafinkitxmlcodeinlinelatexdvp et kitxmlcodeinlinelatexdvpbfinkitxmlcodeinlinelatexdvp et retourne une approximation de l'intégrale de kitxmlcodeinlinelatexdvpffinkitxmlcodeinlinelatexdvp de kitxmlcodeinlinelatexdvpafinkitxmlcodeinlinelatexdvp à kitxmlcodeinlinelatexdvpbfinkitxmlcodeinlinelatexdvp par la méthode des trapèzes. Comparer son résultat avec la valeur quasi-exacte.

Méthode des trapèzes : si kitxmlcodeinlinelatexdvpf\,:\, [a;\,b] \longrightarrow\mathbb{R}finkitxmlcodeinlinelatexdvp est continue,

soit kitxmlcodeinlinelatexdvpa_k = a+k\dfrac{b-a}{n}\,\mathrm{pour}\,k\in[[0;\,n]]finkitxmlcodeinlinelatexdvp (ainsi kitxmlcodeinlinelatexdvpa_0=a, a_n=bfinkitxmlcodeinlinelatexdvp). Si kitxmlcodeinlinelatexdvpnfinkitxmlcodeinlinelatexdvpest assez grand :

kitxmlcodelatexdvp\begin{aligned} \int^b_a f(x)\textrm{d}x&\approx\left(\dfrac{b-a}{n}\right)\sum^{n-1}_{k=0} \dfrac{f(a_k)+f(a_{k+1})}{2}\\ &\approx \left(\dfrac{b-a}{n}\right)\left( \dfrac{f(a)+f(b)}{2}+\sum^{n-1}_{k=1} f(a_k)\right) \end{aligned}finkitxmlcodelatexdvp
Méthode des trapèzes

Cliquez sur l'icône Image non disponible.

Méthode des trapèzes
Cacher/Afficher le codeSélectionnez

la boucle for permet de calculer la somme.

Image non disponible
  • L'instruction '+=' : a += b donne le même résultat que a = a + b. Elle lui est préférable, car plus rapide : dans le premier cas, la valeur de b vient s'ajouter à celle de a, dans le deuxième, les valeurs de a et b sont d'abord dupliquées en mémoire avant d'être additionnées entre elles puis le résultat est affecté à la variable a. On dispose aussi des opérateurs : '-=', '*=', '\=', etc.

On peut améliorer la fonction en prenant la fonction à intégrer et le pas en paramètres : trapeze(f, a, b, n).

La fonction à intégrer est définie par :

 
Sélectionnez
def carre(x) :
    return x**2

Cliquez sur l'icône Image non disponible.

 
Cacher/Afficher le codeSélectionnez

À l'exécution :

Image non disponible

précédentsommairesuivant

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2014 Jean-Philippe PREAUX. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.