Vous êtes sur la page 1sur 28

Programmation en Python

L1 MIASHS
Nadia Creignou Frédéric Olive

Table des matières


1 Les variables et leurs types 2

2 Dialoguer avec la machine : les entrées/sorties. 4

3 Structures de contrôle 6

4 Fonctions 10

5 Listes 15

6 Fichiers 22

7 Dictionnaires 26

Préambule
Avertissement : ce document n’a pas vocation à être un ouvrage de référence. Il recense des notes de
cours, parfois informelles, dans le but de faciliter un travail personnel des étudiants. Ceux-ci sont invités
à se référer aux ouvrages mentionnés dans le corps de ce document.

Python est un langage de programmation autorisant la programmation impérative et la programmation


objet. Il est portable, utilisable sur Mac OS, Windows et Linux. Le site officiel de Python est https:
//www.python.org/. Vous pouvez y télécharger gratuitement le langage Python dans la version 3.6.5
correspondant au système d’exploitation que vous utilisez.
Le langage Python est utilisé pour écrire des programmes simples aussi bien que des projets très com-
plexes. Il peut s’adapter à de nombreux contextes grâce à des bibliothèques spécialisées. Il est particuliè-
rement répandu dans le monde scientifique, et prisé par certains pédagogues qui y trouvent un langage
dont la syntaxe est claire et permet une initiation aisée aux concepts de base de la programmation.
Nous présentons ici une introduction très succincte à Python. Ce cours est complété par des TD et
des TP qui suivront son déroulement. L’ouvrage de référence que nous vous recommandons et sur lequel
nous nous appuierons est Apprendre à programmer avec Python 3 de Gérard Swinnen (Editions Eyrolles),
disponible en ligne gratuitement en version pdf : https://inforef.be/swi/download/apprendre_
python3_5.pdf.

1
On peut utiliser Python directement comme une calculatrice avec la ligne de commande python3
dans un terminal, et en écrivant directement en ligne les opérations souhaitées. On peut également ouvrir
un éditeur de texte, y taper un programme python que l’on sauvegarde avec l’extension .py, par exemple
sous le nom monpremierprogramme.py, et que l’on interprète ensuite dans un terminal avec la commande
python3 monpremierprogramme.py. Il est plus pratique d’utiliser des outils adaptés. On utilisera dans
ce cours Idle3 qui est automatiquement installé avec Python3 (il existe d’autres outils possibles). Cet
outil très simple d’utilisation permet de d’ouvrir des fichiers pour y écrire des scripts variés, de les sau-
vegarder, puis de les exécuter. La syntaxe de python est simple, mais l’indentation est primordiale. Le
langage python est sensible à l’emploi des majuscules. Dans toute la suite on notera >>> pour indiquer
que l’on se trouve dans l’évaluateur Python, dans un énoncé ce symbole indique que vous avez la main.

1 Les variables et leurs types


Une variable est un objet qui possède un nom, qui fait référence à un espace mémoire de l’ordinateur
dans lequel est stockée la valeur de la variable, qui représente donc une donnée. Les noms des variables
en Python sont des séquences de lettres et de chiffres (sans caractères spéciaux ni accentués) qui doivent
commencer par une lettre. Quelques mots réservés du langage (comme print, vu en TD) sont exclus.
Il est recommandé de choisir des noms de variables qui reflètent leur rôle/leur sens dans le programme.
L’affectation d’une valeur à une variable se fait à l’aide du signe = .
1 >>> longueur = 5
2 >>> phrase = ’bonjour tout le monde ’

On peut faire plusieurs affectations en même temps.


1 x, y = 2.4, 6

L’affectation crée et mémorise un nom de variable, crée et mémorise une valeur particulière et crée
une association entre le nom et la valeur.
Comme tout langage de programmation, Python comprend des types de données élémentaires permet-
tant notamment de travailler directement avec des nombres, des caractères et des chaînes de caractères.
En Python le typage se fait de façon dynamique au moment de l’affectation. L’affectation d’une valeur à
une variable est temporaire, la valeur d’une variable peut-être modifiée à tout moment, et de ce fait son
type également.
1 >>> x,y,ph = 2.4, 6, " bonjour "
2 >>> print (x)
3 2.4
4 >>> type(x)
5 <class ’float ’>
6 >>> print (y)
7 6
8 >>> type(y)
9 <class ’int ’>
10 >>> y = x
11 >>> print (y)
12 2.4
13 >>> type(y)
14 <class ’float ’>
15 >>> type(ph)
16 <class ’str ’>
17 >>> type ((1,3))
18 <class ’tuple ’>

2
Les nombres. Sur les nombres on distingue Integer les entiers, Float les nombres à virgule et
Complex les complexes. Ces derniers se notent par exemple 2 + 3 j, et le coefficient devant j doit tou-
jours être précisé, par exemple l’imaginaire pur i sera représenté en Python par 1 j.
1 >>> Z = 1+2j
2 >>> Q = 1+3j
3 >>> type(Z)
4 <class ’complex ’>
5 >>> Z+Q
6 (2+5j)
7 >>> Z*Q
8 (-5+5j)

Les quatre opérations élémentaires sont pré-définies. Il y a d’autres fonctions mathématiques pré-
définies, pour des fonctions plus élaborées il faudra faire appel à une bibliothèque spécialisée (cela sera
vu plus tard dans le cours).
Il n’y a pas que des nombres, mais également les chaînes de caractères (String), les tuples (Tuple),
les listes (ou tableaux), les dictionnaires. . .

Les chaînes de caractères string. Une chaîne de caractère string est une suite de caractères délimi-
tée par des guillemets ou des apostrophes (ces guillemets ou apostrophes ne faisant bien évidemment pas
partie de la chaîne). Les chaînes de caractères supportent les opérations + et *. La fonction len donne la
longueur de la chaîne.
1 >>> ch1 = ’bonjour ’
2 >>> len(ch1)
3 7
4 >>> ch1*3
5 ’bonjourbonjourbonjour ’
6 >>> ch2 = ’ tout le monde ’
7 >>> ch1 + ch2
8 ’bonjour tout le monde ’

Une chaîne est une séquence : les caractères de la chaîne sont numérotés, on dit qu’ils ont un indice.
(numéroté à partir de 0). Si ch est une chaîne, ch[i] renverra le caractère d’indice est i de la chaîne. Il y a
une double indexation : de la gauche vers la droite avec des nombres positifs de 0 à n − 1 (si n est la taille
de la chaîne) et de la droite vers la gauche avec des nombres négatifs commençant à -1. On peut donc
accéder à une lettre de la chaîne ou à une sous-chaîne.
b o n j o u r !
0 1 2 3 4 5 6 7
-8 -7 -6 -5 -4 -3 -2 -1

Attention on ne peut pas modifier une chaîne, il faudra recopier une chaîne pour la modifier.
1 >>> mot = ’demin ’
2 >>> mot[1]
3 ’e’
4 >>> mot[-2]
5 ’i’
6 >>> mot[0:4]
7 ’demi ’
8 >>> mot[4]
9 ’n’
10 >>> mot[3] = ’a’
11 Traceback (most recent call last):
12 File "<pyshell #25 >", line 1, in < module >

3
13 mot[3] = ’a’
14 TypeError : ’str ’ object does not support item assignment
15 >>> motbis = mot[0:3] + ’ai ’ + mot[4]
16 >>> motbis
17 ’demain ’

Les tuples. Le tuple permet de regrouper des éléments (de n’importe quel type). C’est une donnée
« composée » ou « composite ». C’est une séquence (les éléments sont numérotés).
1 >>> t = (2,3,4,5)
2 >>> type(t)
3 <class ’tuple ’>
4 >>> s = (2 ,) # ne pas oublier la virgule pour un tuple à un élément
5 >>> x = () # tuple vide
6 >>> print (x)
7 ()
8 >>> y = (1, (2,3), 6) # tuple contenant un tuple

Comme pour les strings, on a accès aux éléments par leur indice, on peut découper des morceaux mais
on ne peut pas modifier un tuple.

’jan’ ’fev’ ’mar’ ’avr’ ’mai’ ’jui’


0 1 2 3 4 5
-6 -5 -4 -3 -2 -1

1 >>> nom_mois = (’jan ’, ’fev ’, ’mars ’, ’avr ’, ’mai ’, ’juin ’)


2 >>> nom_mois [4]
3 ’mai ’

2 Dialoguer avec la machine : les entrées/sorties.


L’affichage (les sorties). print permet l’affichage de données (n’importe lesquelles). C’est une fonc-
tion donc il y aura des parenthèses. La commande print n’affiche pas les guillemets ou apostrophes
externes d’une chaîne de caractères. On peut fabriquer une chaîne regroupant plusieurs données avant de
faire l’affichage, mais on peut aussi mettre plusieurs paramètres avec des virgules et utiliser sep= (c’est
optionnel).
1 >>> print (’bonne ’,’année ’,2022)
2 bonne année 2022
3 >>> print (’bonne ’+’année ’+ str(2022))
4 bonneannée2022
5 >>> print (’bonne ’+ " "+’année ’+ " "+ str(2022))
6 bonne année 2022
7 >>> print (’bonne ’,’année ’,2022 , sep="*")
8 bonne* année*2022

Saisie (les entrées). Il faut pouvoir saisir une réponse donnée par l’utilisateur. Pour cela on utilise
input, par exemple input(’la chaîne que vous voulez’) affiche la chaîne que vous voulez
et attend une entrée clavier ; cette fonction renvoie une chaîne de caractères contenant la donnée saisie
par l’utilisateur. Il conviendra donc de faire les changements de types nécessaires pour d’éventuels calculs.
Par exemple l’exécution du script ci-dessous :

4
1 >>> print (" bonjour ")
2 >>> a = input("quel est votre prenom ? ")
3 >>> print (" comment allez -vous "+ a+ " ?")
4 >>> print ("on va faire un calcul ")
5 >>> x = input(" entrez un nombre : ")
6 >>> y = input(" entrez un autre nombre : ")
7 >>> print ("la somme de "+ x+ " et " + y + " est égale à "+ (x+y))
8 >>> print (’en transformant les nombres lus au clavier en flottants on obtient \n
’)
9 >>> print ("la somme de "+ x+ " et " + y + " est égale à "+str(float (x)+ float (y)
))
10 >>> # la commande suivante convient également
11 >>> print ("la somme de ",x, " et ", y, " est égale à ", float (x)+ float(y))

fournit
1 bonjour
2 quel est votre prenom ? Alice
3 comment allez -vous Alice ?
4 on va faire un calcul
5 entrez un nombre : 3
6 entrez un autre nombre : 7
7 la somme de 3 et 7 est égale à 37

En transformant les nombres lus au clavier en flottants on obtient


1 la somme de 3 et 7 est égale à 10.0
2 la somme de 3 et 7 est égale à 10.0

Attention, si on veut entrer un tuple au clavier, on a besoin de la fonction eval.


1 >>> ch = tuple (input(’entrez votre sequence avec des virgules : ’))
2 entrez votre sequence avec des virgules : 1,2,3
3 >>> ch
4 (’1’, ’,’, ’2’, ’,’, ’3’)
5
6 >>> ch = tuple (eval( input (’entrez votre sequence avec des virgules : ’)))
7 entrez votre sequence avec des virgules : 1,2,3
8 >>> ch
9 (1, 2, 3)
10 >>> ch[1]
11 2

On peut également « fabriquer » de nouvelles chaînes en insérant des variables. Dans la chaîne qu’on
veut fabriquer on met %s à chaque position où on voudrait qu’il y ait une variable puis on indique avec %
les variables à insérer. Par exemple :
1 >>> x, y = 3, 5
2 >>> print ("on a x = %s", %x)
3 SyntaxError : invalid syntax
4
5 >>> print ("on a x = %s" %x)
6 on a x = 3
7
8 >>> ch = "on a x = %s" %x
9 >>> ch
10 ’on a x =3’
11
12 >>> c = "la somme de %s et %s fait %s" %(x,y,x+y)
13 >>> print (c)
14 la somme de 3 et 5 fait 8

5
3 Structures de contrôle
Pour tester l’égalité des deux objets en Python on utilise le test == . Cela convient pour tous les types
de données. L’inégalité se teste avec != . On peut également utiliser d’autres opérateurs de comparaisons,
comme > , ou <= par exemple.
Un booléen est un objet qui ne prend prendre que deux valeurs, vrai (True) ou faux (False).
Dans des programmes on peut désirer exécuter certaines instructions sous certaines conditions. Une
condition est une expression logique qui, lorsqu’elle est exécutée, prend une valeur booléenne. Les condi-
tions élémentaires sont construites avec les opérateurs de comparaison ci-dessus. Elles peuvent être com-
binées entre elles en utilisant les connecteurs logiques and, or et not.

3.1 La conditionnelle si . . . alors . . . sinon


On utilise les instructions d’exécution conditionnelle suivantes :
1 if ( condition ):
2 bloc d’instructions 1

ou
1 if ( condition ):
2 bloc d’instructions 1
3 else:
4 bloc d’instructions 2

Notez que l’on peut avoir besoin d’un else (mais ce n’est pas obligatoire), les “ : ” à la fin de la ligne
if sont obligatoires et que l’indentation est importante (elle est automatique avec tout éditeur adapté).
Remarquez que les instructions if et else sont alignées, les deux “blocs” d’actions le sont aussi. En
Python les blocs d’instructions sont délimités par les niveaux d’indentation. Un bloc d’instruction peut
contenir tout ce que l’on veut, il est donc possible d’imbriquer les unes dans les autres des instructions
d’exécution conditionnelle. Le programme suivant affiche si le nombre saisi par l’utilisateur est pair ou
impair.
1 nb = int(input(" entrez un entier : "))
2 if (nb%2 == 0):
3 print (nb , ’est pair ’)
4 else:
5 print (nb , ’est impair ’)

Dans le programme suivant les structures de contrôle sont imbriquées. Il s’agit de contrôler si l’utili-
sateur saisit bien un entier pair compris entre 0 et 10.
1 nb = int(input(" entrez un entier pair compris entre 0 et 10 : "))
2 if (nb%2 == 0) and (nb >= 0) and (nb <= 10):
3 print (nb , ’a les bonnes propriétés ’)
4 else:
5 if (nb%2 != 0):
6 print(nb , "n’est pas pair")
7 else:
8 if (nb < 0):
9 print (nb , ’ est negatif ’)
10 else:
11 print (nb , ’ est plus grand que 10 ’)

Une dernière instruction conditionnelle est celle qui utilise elif (qui peut correspondre à sinon si).
Elle permet une écriture plus simple d’un else qui contient un if comme première instruction.

6
1 if ( condition 1):
2 bloc d’instructions 1
3 elif ( condition 2):
4 bloc d’instructions 2
5 elif ( condition 3):
6 bloc d’instructions 3
7
8 else:
9 bloc d’instructions

Le programme exécute les instructions correspondant à la première condition satisfaite rencontrée (et
sort du if ensuite), else n’est pas obligatoire, dans ce cas si aucune condition n’est satisfaite, il ne se
passe rien. Cette instruction elif est particulièrement adaptée au cas où l’on doit tester plusieurs valeurs
pour une même valeur. Par exemple le programme ci-dessus peut-être écrit de la façon suivante.
1 nb = int(input (" entrez un entier pair compris entre 0 et 10 : "))
2 if (nb%2 == 0) and (nb >= 0) and (nb <= 10):
3 print (nb , ’a les bonnes propriétés ’)
4 elif (nb%2 != 0):
5 print (nb , "n’est pas pair")
6 elif (nb < 0):
7 print (nb , ’ est negatif ’)
8 else:
9 print (nb , ’ est plus grand que 10 ’)

3.2 La boucle for


Il s’agit de répéter l’exécution d’un bloc de programmes un certain nombre de fois. On aura des
boucles du style :
— pour i entre 1 et n faire. . .
— pour x dans le tuple faire. . .
— pour x dans la chaîne faire. . .
(et plus tard dans un dictionnaire, un fichier ouvert en lecture, un tableau....) Une telle boucle s’écrit de la
façon suivante :
1 for <truc> in < sequence >:
2 <bloc instructions1 > # à chaque étape de la boucle
3 <bloc instructions2 > # quand la boucle est finie

Attention, le in permet de parcourir une séquence ou de tester l’appartenance d’un élément à un tuple,
à une chaîne. . . (et plus tard à d’autres objets python). Par exemple :
1 >>> 4 in (3,4,5):
2 True
3 >>> "4" in " 56745 "
4 True

On peut tester l’inclusion d’une sous-chaîne, mais pas d’un sous-tuple


1 >>> "34" in " 346243 "
2 True
3 >>> (2,3) in (1,2,3,4) # le sous -tuple est inclus
4 False
5 # mais il n’appartient pas
6 >>> (2,3) in (1 ,(2,3),4) # là il appartient
7 True

7
Par exemple, etant donné une liste d’entiers donnée sous forme d’un tuple, le script suivant calcule la
somme de ces entiers.
1 listedentiers =(2,5,9,1,8,9,4)
2 somme=0
3 for nb in listedentiers :
4 somme +=nb
5 print(’la somme des entiers de cette liste est ’, somme )

Le programme suivant compte le nombre d’occurrences de la lettre ’e’ dans une chaîne de caractères.
1 chaine =’les amis bonjour ’
2 compteur =0
3 for c in chaine :
4 if (c==’e’):
5 compteur +=1
6 print(’il y a %s e dans la phrase %s’ %(compteur , chaine ))

Un tuple peut contenir des tuples. Prenons par exemple un jeu de Uno, chaque carte a une couleur
et une valeur. Etant donné un ensemble de cartes on peut le parcourir et par exemple compter les cartes
rouges. Le programme est alors le suivant :
1 jeu=((2,’rouge ’) ,(4,’jaune ’) ,(3,’rouge ’))
2 cp=0
3 res=()
4 for carte in jeu:
5 if carte [1]==’rouge ’:
6 cp+=1
7 res+=(carte ,)
8 print(’nb de cartes rouges ’, cp)
9 print(’les cartes rouges sont :’, res)

et il affichera
1 nb de cartes rouges 2
2 les cartes rouges sont : ((2, ’rouge ’), (3, ’rouge ’))

Pour calculer la somme des carrés des entiers de 1 à 10 inclus on a besoin de la séquence formée des
10 premiers entiers pour que for puisse la parcourir.
1 t = (1,2,3,4,5,6,7,8,9,10)
2 som = 0
3 for p in t:
4 som = som + p*p
5 print(som)

La fonction range qui peut fabriquer cette séquence. Cette fonction peut avoir 1, 2 ou 3 arguments :
— range(n) crée la séquence des entiers de 0 à n - 1 ;
— range(p,n) crée la séquence des entiers de p à n - 1 ;
— range(p,n,s) crée la séquence des entiers à partir de p en rajoutant s à chaque fois jusqu’à
atteindre ou dépasser n - 1.
Ainsi on peut calculer la somme des carrés des entiers de 1 à 10 inclus de la façon suivante :
1 n = 10
2 som = 0
3 for p in range(1,n+1): # n+1 si on veut que n soit inclus
4 som = som + p*p # ou alors som += p**2
5 print(som)

8
On peut bien sûr imbriquer une boucle dans une boucle.
1 res = 0
2 n = 8
3 for j in range (1,n+1): # n compris
4 for i in range (1,j+1): # j compris
5 res += i+j
6 print (res)

3.3 La boucle While


L’instruction while permet de répéter des tâches « tant que ». Toutes les boucles écrites jusqu’à
présent auraient pu être écrites avec while (mais pas forcément plus simplement). Les boucles qui ne
correspondent pas au parcours d’une séquence ne peuvent pas être écrites avec for, comme jouer jusqu’à
la fin de la partie, ou calculer jusqu’à dépasser une valeur ou atteindre une limite. La syntaxe est la
suivante :
1 while <test>:
2 < instructions1 >
3 else:
4 < instructions2 >

Le else et le deuxième bloc étant facultatifs. Ce qui revient à :


1 while <test>:
2 < instructions1 >
3 < instructions2 >

Affichons par exemple les nombres entiers dans l’ordre décroissant de 15 à 1 :


1 x = 15 # initialisation
2 while x > 0: # attention ne pas oublier le caractère ’:’
3 print (x) # attention à bien mettre ces deux instructions
4 x = x-1 # avec la même indentation dans le while

La série S n = np=1 1/p diverge vers l’infini. Supposons que l’on cherche le plus petit entier n pour
lequel S n dépasse une certaine valeur A.
1 res = 0
2 p = 1
3 print (p)
4 A = 4
5 print (A)
6 while res < A: # la boucle continue tant qu’on n’a pas atteint A
7 res += 1/p
8 p += 1
9 print (’ pour atteindre la somme ’, A, ’il faut aller jusqu au rang ’, p-1)

Comparaison entre while et for :


— while peut faire absolument toutes les boucles alors que for est prévu pour faire des parcours de
séquences (ou de dictionnaires, de fichiers).
— for est éventuellement plus vite écrit (gestion automatique de la variable de parcours : initialisation
et i = i + step).
— for n’est pas pratique pour des boucles dans lesquelles l’incrémentation ne se fait pas à chaque
étape ou pas régulièrement.
— while ne peut pas parcourir une chaîne caractères par caractères mais uniquement par les indices
des caractères (idem pour les tuples, listes, etc).

9
4 Fonctions
L’un des concepts les plus importants en programmation est celui de fonction. Les fonctions per-
mettent de décomposer un programme complexe en une série de programmes plus simples, qui peuvent à
leur tour être décomposés. De plus une fois qu’une fonction est définie elle est réutilisable. Imaginons que
nous disposions d’une fonction qui permet de calculer l’aire d’un rectangle. Nous pouvons alors l’utiliser
un peu partout dans notre programme sans avoir à la ré-écrire à chaque fois.

4.1 Fonctions prédéfinies de base.


Il existe beaucoup de fonction prédéfinies dans le “pack” python de base.

La fonction print() Cette fonction permet d’afficher une ou plusieurs valeurs fournies en arguments.
1 >>> print (" bonjour ", "à", "tous")
2 bonjour à tous

Interaction avec l’utilisateur : la fonction input(). Cette fonction provoque l’interruption du pro-
gramme courant. On peut placer en argument un message explicatif pour l’utilisateur. L’utilisateur est
alors invité à entrer des caractères au clavier et à terminer en appuyant sur la touche Enter. Une fois
cette touche enfoncée le programme se poursuit et la fonction fournit en retour une chaîne de caractères
correspondant à ce que l’utilisateur a saisi. Cette chaîne peut alors être convertie, assignée à une variable,
etc. Rappelons que la fonction input() renvoie toujours une chaîne de caractères. Si vous souhaitez que
l’utilisateur entre une valeur numérique il faut alors la convertir par l’intermédiaire des fonctions int()
(si vous attendez un entier) ou float() (si vous attendez un réel). Le script suivant est un exemple.
1 prenom = input(’entrez votre prenom ’)
2 age = int(input (’entrez votre âge ’))
3 print(’bonjour ’,prenom ,’dans 10 ans vous aurez ’,age+10 ,’ans ’)

4.2 Fonctions prédéfinies dans des modules


Beaucoup d’autres fonctions sont rangées dans des modules (ou bibliothèques) qui ne sont pas chargés
au lancement de Python. Certains de ces modules sont dans la distribution de base de Python, d’autres
doivent être installés.

Le module math. Par exemple, sin et cos ne sont pas présentes dans le pack de base contrairement à
pow. La racine carrée, sqrt non plus n’est pas dans le chargement de base. Mais ces fonctions sont dans
le module math présent dans la distribution de base.
On peut importer une fonction du module math, par exemple la fonction sqrt, par l’instruction :
1 from math import sqrt

ou toutes les fonctions du module math avec l’instruction :


1 from math import * # l’astérisque indique qu’il faut tout importer

Le script suivant décrit une utilisation possible des fonctions du module math.

10
1 from math import *
2 nombre = 121
3 angle = pi/6 # la biliothèque math contient la définition de pi
4
5 print ("la racine carree de ", nombre , "est", sqrt( nombre ))
6 print ("le sinus de l’angle ", angle , "est", sin( angle ))

Le module random. Pour pouvoir traiter tout ce qui est aléatoire on a besoin du module random.
1 from random import *

Mentionnons quelques fonctions parmi les plus utiles :


— randint (a,b) : renvoie aléatoirement un entier compris entre a et b (inclus tous les deux). At-
tention : a et b doivent être entiers (négatifs éventuellement).
— random () : renvoie aléatoirement un réel compris entre 0 (inclus) et 1 (exclu).
— Choice(seq) : renvoie un élément au hasard dans la séquence non vide seq (si seq est vide cela
provoque une erreur) ; la séquence peut être une liste, une chaîne, un tuple ...
.

Le module turtle. C’est un module de dessin, une tortue se déplace et peut marquer ces déplacements.
Les principales fonctions sont les suivantes :
— up() : lève le crayon.
— down() : baisse le crayon.
— forward(d) : fait avancer la tortue de d, le trait est dessiné si le crayon est baissé.
— backward(d) : fait reculer la tortue de d, le trait est dessiné si le crayon est baissé.
— left(a) : fait pivoter la tortue d’un angle de a degrés vers la gauche.
— right(a) : fait pivoter la tortue d’un angle de a degrés vers la droite.
— reset() : nettoie la fenêtre de dessin, réinitialise la tortue : elle est au centre de l’écran de dessin
tournée vers la droite.
— home() : remet la tortue au centre avec son cap (attention si le crayon est baissé il y a un tracé),
n’efface rien.
— color(c) : la couleur par défaut est le noir. On peut changer en mettant une couleur : c doit être
une chaîne prédéfinie red, green, blue, yellow (in english of course).
— bgcolor(c) : modifie la couleur de fond (blanc par défaut).
— dot(d,c) : dessine un disque de diamètre d et de couleur c là où est la tortue.
— circle(r) : trace un cercle de rayon r, le point de départ de la tortue appartient au cercle (attention
il n’est pas centré sur la position de la tortue).
— circle(r,s) : trace une portion du cercle correspondant à s degrés.
— width(e) : fixe la largeur du trait (en pixel).
— write(ch) : permet d’écrire la chaîne ch là où est la tortue.
— goto(x,y) : la tortue va se positionner au point de coordonnées (x,y) (le trait est tracé si le crayon
est baissé).
— setheading(a) : où a est en degré permet de fixer un cap absolu à la tortue.

11
— speed(vitesse) : permet de fixer une vitesse à la souris. L’argument peut être ’fastest’, ’fast’,
’normal’, ’slow’ ou ’slowest’ .
— hideturtle() et showturtle() : permettent de supprimer le curseur ou de le remettre.
— begin_fill() et end_fill() permettent de remplir une figure géométrique en encadrant par ces
instructions le dessin à remplir.
Par exemple le script suivant permet de dessiner un rectangle dont les côtés sont successivement tracés
en noir (par défaut), rouge, vert et bleu.
1 from turtle import *
2
3 forward (120)
4 left(90)
5 color (’red ’)
6 forward (80)
7 left(90)
8 color (’green ’)
9 forward (120)
10 left(90)
11 color (’blue ’)
12 forward (80)

On peut obtenir des figures plus élaborées en introduisant des boucles. Par exemple on obtient une
étoile à six branches ainsi :
1 from turtle import *
2 reset ()
3 nb_branches =0
4 while nb_branches <=6:
5 nb_branches +=1
6 forward (200)
7 left(150)

Il existe beaucoup d’autres modules, comme par exemple :


— pour des calculs : numpy, scipy ;
— visualisation : mathplotlib ;
— graphisme : turtle, pil, pygame ;
— pour des traitements de fichiers : os ;
— pour des interfaces graphiques : Tkinter ;

Des fonctions particulières : les méthodes. Les méthodes sont des fonctions prédéfinies un peu par-
ticulières. Elles sont associées à un objet (elles font partie de la définition de ce qu’on appelle la classe
d’un objet). Leur utilisation est particulière : si truc est un objet (tuples, chaînes, listes) pour lesquels
une méthode machin existe alors l’utilisation sera : truc.machin(arguments). On verra plus tard de
nombreuses méthodes pour les listes.

4.3 Fonctions originales


Créer de nouvelles fonctions. On peut créer des fonctions, avec ou sans paramètre. Une fois une fonc-
tion définie elle peut-être utilisée dans le programme comme les fonctions prédéfinies. La syntaxe est la
suivante :
1 def nom_fonction (arg1 , arg2 ,..):
2 bloc d’instructions

12
arg1, arg2... sont appelés les paramètres (ou arguments) de la fonction. Une fonction peut contenir un
nombre quelconque de lignes, contenir ou pas des boucles, des tests. . . Il n’y a pas de déclaration de type.
Par exemple la fonction suivante permet de calculer l’aire d’une rectangle.
1 def AireRectangle (long , larg):
2 print (long*larg)

Une fois cette fonction définie, on peut y faire appel.


1 >>> AireRectangle (10 ,4)
2 40

En fait la définition de cette fonction n’est pas satisfaisante car on ne peut se servir du résultat fourni.
Par exemple le programme suivant fournit une erreur :
1 >> x= AireRectangle (23 ,12)
2 276
3 >>> x+3
4 Traceback (most recent call last):
5 File "<pyshell #28 >", line 1, in - toplevel -
6 x+3
7 TypeError : unsupported operand type(s) for +: ’NoneType ’ and ’int ’

Cela vient du fait que dans le programme ci-dessus x n’a pas de valeur (ou la valeur none), car la
dernière ligne du corps de la fonction est un print, qui est une fonction d’affichage. Pour renvoyer une
valeur il faut utiliser return. La fonction de calcul de l’aire d’un rectangle s’écrit donc :
1 def AireRectangle (long , larg):
2 return (long*larg)

Une fois cette fonction définie on peut l’utiliser, et utiliser les résultats qu’elle fournit. Elle peut-être
utilisée dans le programme principal, mais également dans le corps d’une autre fonction.
1 >>> x = AireRectangle (3,4)
2 >>> y = AireRectangle (2,5)
3 >>> print (’x+y=’, x+y)
4 x+y= 22

Remarque très importante : return provoque automatiquement une sortie de la boucle en cours.
Ainsi par exemple quand on exécute le programme suivant :
1 def ContientUnA ( chaine ):
2 for lettre in chaine :
3 if lettre == ’a’:
4 return True
5 return False
6
7 print (’le mot maths contient un a? ’, ContientUnA (’maths ’))
8 print (’le mot python contient un a? ’, ContientUnA (’python ’))

on obtient
1 le mot maths contient un a? True
2 le mot python contient un a? False

et la fonction ContientUnA teste bien si la chaîne de caractères donnée en argument contient le caractère
’a’.
On peut aussi faire une fonction sans argument pour appeler des programmes, typiquement si on veut
demander des arguments à l’utilisateur.

13
Supposons que la fonction compte(c,ch) ait été définie et qu’elle renvoie le nombre d’occurrences
du caractère c dans la chaîne ch, alors la fonction prog ci-dessous est une fonction sans argument, qui
sert à établir un dialogue avec l’utilisateur.
1 def prog ():
2 c = input(" caractère à compter ")
3 ch = input ("dans quelle chaîne ? ")
4 compte (c, ch)

Une fois cette fonction créée on peut y faire appel.


1 >>> prog ()
2 caractère à compter o
3 dans quelle chaîne ? j’aime trop python
4 2

Attention pour appeler la fonction il est important d’écrire prog() et non pas prog, même si cette
fonction n’a pas d’arguments.
Attention à bien mettre le nombre d’arguments prévus et n’oubliez pas de lire les messages d’erreur.
Ce n’est pas forcément le programme qui est faux, cela peut être l’appel.

Les fonctions pour plus de modularité. Un grand intérêt des fonctions est de pouvoir découper les
tâches en plus petites tâches : on peut définir des fonctions auxiliaires pour simplifier l’écriture d’autres
fonctions. Par exemple pour chercher le plus grand parmi quatre nombres, on peut commencer par cher-
cher le plus grand de deux nombres.
1 def max2 (x,y):
2 if x< y:
3 return y
4 else:
5 return x
6
7 def max4(x,y,z,t):
8 return max2(max2 (x,y), max2(z,t))

Un autre exemple est celui d’une fonction qui compte le nombre de voyelles dans une chaîne de
caractères :
1 def isVowel (c):
2 return c in ("a","e","i","o","y","u")
3
4 def countVowels ( texte ):
5 cp = 0
6 for x in texte :
7 if isVowel (x):
8 cp = cp+1
9 return cp
10
11 >>> countVowels (" bonjour tout le monde")
12 8

Variables globales, variables locales. Les variables globales sont les variables utilisées au début de ce
cours. Elles sont définies en dehors des fonctions et les fonctions peuvent les utiliser. On utilise aussi des
variables locales qui sont définies et accessibles uniquement à l’intérieur d’un programme.
1 def sommeCube (n):
2 s = 0

14
3 for k in range (n+1):
4 s += k ** 3
5 return s

La variable s est une variable locale au programme sommeCube. On ne peut pas connaître sa valeur en
dehors de l’intérieur de ce programme. Du coup, même si on a plusieurs fonctions utilisant des variables
locales de même nom, il n’y aura pas de conflit.

4.4 Bonnes pratiques


On portera une attention particulière au nommage des fonctions, de préférence (ce qui n’est pas res-
pecté dans ce cours) en utilisant l’anglais. Il est recommandé de s’inspirer du nommage des fonctions
pré-définies dans les différents modules.

— Si une fonction est une commande dont le but est d’agir, son nom doit décrire cette action. Son
nom contiendra donc au moins un verbe à l’infinitif.
— Si une fonction correspond à une requête booléenne (prédicat), c’est à dire répond par vrai ou faux
à une question fermée, alors son nom doit contenir un verbe conjugué au présent de l’indicatif et le
sujet du verbe. Par exemple ...
1 def NbIsOdd (n):
2 if n%2 == 1:
3 return True
4 else:
5 return False

Puisque le test == est lui même un prédicat on n’écrira pas if NbIsOdd(n)==True: ..., mais
directement if (NbIsOdd(n)): ....
— Si un fonction est une requête non booléenne, et répond donc à une question ouverte, on peut le
nommer comme une commande et donc utiliser un verbe à l’infinitif qui exprime la recherche, le
calcul etc .... Parfois on peut omettre le verbe pour obtenir une forme nominale, comme cela a été
fait pour la fonction AireRectangle(long, larg).

Un bon programme est un programme documenté : toute fonction doit être précédée de sa description.

5 Listes
Le type list est un type séquentiel, ou une séquence. Cela signifie plusieurs choses.
— D’abord, c’est un type composite, par opposition aux type simples comme les types int, float,
bool. . . Une liste agglomère plusieurs éléments et ces éléments peuvent être de différents types.
— Ensuite, les éléments d’une listes sont ordonnés et indexés par des entiers.
— Enfin, cette indexation permet de parcourir les élément de la liste, ou d’accéder à un élément parti-
culier à partir de son indice.
Nous avons déjà rencontré trois types séquentiels : les chaînes de caractères (str), les tuples (tuple)
et les ranges (range). Ces trois types sont non modifiables (on dit aussi non mutables, ou immuables).
Par exemple, après création d’un tuple référencé par une variable t :
1 >>> t = (1,3,5,7)

15
l’instruction t [ 3 ] = 0, qui prétend remplacer l’élément d’indice 3 dans t par la valeur 0, déclenche
un message d’erreur. Ceci parce que l’espace mémoire « pointé » par une variable de type tuple ne peut
pas être modifié. Bien sûr, on peut réaffecter la variable t à un nouveau tuple (stocké dans un nouvel
espace mémoire) via l’instruction t = (1,3,5,0), par exemple, mais ceci a pour effet de faire pointer
la variable t vers un nouvel espace mémoire contenant le tuple (1,3,5,0), et non de modifier le tuple
initial.
Ainsi, les types str, tuple et range ne permettent pas de modifier des données séquentielles qui
évoluent au cours du temps. Il s’agit pourtant là d’un besoin très standard des applications informatiques
(pensez par exemple à la gestion d’une base de données, qui nécessite des mises à jour fréquentes des
données stockées dans la base).
Le type de donnée list introduit dans cette section répond à ce besoin. Dans une multidude d’usages
il est très proche du type tuple, mais il est modifiable. Les listes se déclarent de la manière suivante
(notez l’usage des crochets, au lieu des parenthèses utilisées pour les tuples) :
1 >>> noms_mois = [" janvier ", " fevrier ", "mars", " avril ", "mai", "juin", " juillet "
, "aout", " septembre ", " octobre ", "
novembre ", " decembre "]
2 >>> nbjours = [31 ,28 ,31 ,30 ,31 ,30 ,31 ,31 ,30 ,31 ,30 ,31]
3 >>> entierspremiers = [2,3,5,7,11 ,13 ,17 ,19]
4 >>> jeucarte = [["valet ", "coeur "],["valet ", "pique "], ["dame"," carreau "],["as",
" trefle "]]
5 >>> etud = [" dupont "," pierre ",[12 ,3,1987], "info", " 0231675423 ",12 ,4,15]

On dispose pour les listes de fonctions similaires à celles pour les tuples :
— len(l) : renvoie le nombre d’éléments de la liste l. Il s’agit du nombre d’éléments au "premier
niveau".
1 >>> len( jeucarte ) --> 4
2 >>> len ( entierspremiers ) --> 8
3 >>> len(etud)--> 8

— accès à un élément (comme les tuples) selon son indice.


1 >>> jeucarte [1] --> ["valet", "pique "]
2 >>> entierspremiers [-1]--> 19

— sous-listes (comme pour les tuples)


1 >>> entierspremiers [2:-1]--> [5,7,11 ,13 ,17]

— max(l), min(l) : renvoient respectivement le max et le min des éléments de l si ceux-ci sont
ordonnés.
— sum(l) : renvoie la somme des éléments de l si ceux-ci sont des nombres.
À partir d’une liste, on peut en fabriquer d’autres à l’aide des opérateurs + ou * :
1 >>> l1 = [1,3,5,7]
2 >>> l2 = [8,6,4,2]
3 >>> l3 = [0]
4 >>> l1 } l2
5 [1,3,5,7,8,6,4,2]
6 >>> l1 } l2 } l3
7 [1,3,5,7,8,6,4,2,0]
8 >>> l3 * 6
9 [0,0,0,0,0,0]
10 >>> l1 } [9]
11 [1,3,5,7,9]

16
La fonction list transforme une séquence en une liste :
1 >>> list ("est")
2 [’e’, ’s’, ’t’]
3 >>> list (str (12345 ))
4 [’1’, ’2’, ’3’, ’4’, ’5’]
5 >>> list ((2,5))
6 [2, 5]
7 >>> list (( ’poire ’, ’pomme ’, ’citron ’))
8 [’poire ’, ’pomme ’, ’citron ’]
9 >>> list (((1,2) ,(3,5) ,(3,6)))
10 [(1, 2), (3, 5), (3, 6)]
11

Beaucoup de fonctions s’écrivent comme pour les tuples ou les chaînes. Par exemple compter le
nombre d’éléments égaux à un élément x donné dans une liste l :
1 def compter (x,l) :
2 cp = 0
3 for elt in l :
4 if elt == x :
5 cp }= 1
6 return cp

Extraction des entiers pairs d’une liste d’entiers :


1 def extraireEntiersPairs (l):
2 res = [ ] # on part d’une liste vide
3 for x in l:
4 if x%2 == 0: # test de parité
5 res = res } [x] # attention aux [ ]
6 return res

En résumé, les listes sont très semblables aux tuples à l’exception des [ ] au lieu des ( ). La différence
principale est que la liste est une donnée mutable, c’est à dire à laquelle on peut apporter des modifications
physiques, alors que le tuple est non mutable. Ceci signifie qu’une liste est modifiable de façon interne.
Ainsi, l’instruction
1 l[i] = val

met la valeur val à la place d’index i de la liste l. La liste est modifiée, pas recopiée.
1 >>> liste = [1, 6, 3, 8, 2]
2 >>> liste [4] = 9 # ne renvoie rien
3 >>> liste
4 [1, 6, 3, 8, 9]
5 >>> liste [4] = [1,1,1,1,1]
6 >>> liste
7 [1, 6, 3, 8, [1, 1, 1, 1, 1]]

Attention aux données mutables :


1 >>> x = [0,1,2,3,4,5,6]
2 >>> y = x
3 >>> x[1] = "*"
4 >>> x
5 [0, ’*’, 2, 3, 4, 5, 6]
6 >>> y
7 [0, ’*’, 2, 3, 4, 5, 6]
8 >>> y[2] = "$"
9 >>> y

17
10 [0, ’*’, ’$’, 3, 4, 5, 6]
11 >>> x
12 [0, ’*’, ’$’, 3, 4, 5, 6]

x et y sont modifiés en même temps ! On n’a pas ce problème pour les tranches car une copie est faite
automatiquement.
1 >>> l = [1,2,3,4,5,6,7,8,9]
2 >>> k = l[4:7]
3 >>> k
4 [5, 6, 7]
5 >>> k[1] = 4
6 >>> k
7 [5,4,7]
8 >>> l
9 [1, 2, 3, 4, 5, 6, 7, 8, 9]

On peut aussi faire une copie pour une liste avec


1 >>> m = l[:]

Alors m variera indépendamment de l.

On a d’autres fonctions utiles :


— del l[i ] : supprime la valeur d’indice i de la liste l.
1 >>> l = [1, 6, 3, 8, 2]
2 >>> del l[2]
3 >>> l
4 [1, 6, 8, 2] # c’est l’élément d’indice 2 qui a ’disparu ’ pas la valeur 2

— l [ i : j ] = l2 : remplace la tranche entre i et j - 1 par la liste l2 ; la liste l2 et la tranche


l [ i : j ] peuvent être de longueurs quelconques, non nécessairement égales.
1 >>> l = [1, 6, 3, 8, 2]
2 >>> l[1:3] = [0,0,0,0,0]
3 >>> l
4 [1,0,0,0,0,0,8,2]
5 >>> l[2:] = [7]
6 >>> l
7 [1,0,7]

— del l[i : j ] : supprime la tranche comprise entre les index i et j - 1.


1 >>> l = [1, 2, 3, 4, 5, 6, 7]
2 >>> del l[1:4]
3 >>> l
4 [1, 5, 6, 7]

Dans tous les cas, l’appel d’une telle fonction modifie la liste et retourne None. On ne doit pas écrire :
1 liste = del liste [i]

Dans tous les programmes, il faudra donc voir si on veut renvoyer une nouvelle liste ou modifier celle
existante.

18
Listes et fonction range. La fonction range crée une séquence qui n’est pas une liste. Si on souhaite
la transformer en liste il faut utiliser la fonction list(l).
1 >>> l = range(1,15)
2 >>> l
3 range (1,15) # ce n’est pas une liste c’est un "range"
4 >>> l}l
5 Traceback (most recent call last):
6 File "<pyshell #10 >", line 1, in < module >
7 l}l
8 TypeError : unsupported operand type(s) for }: ’range ’ and ’range ’
9 >>> l = range(1,15)
10 >>> m = list(l) # on transforme le range en liste
11 >>> m
12 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10 , 11 , 12 , 13 , 14]
13 >>> m}m
14 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10 , 11 , 12 , 13 , 14 ,
15 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 , 11 , 12 , 13 , 14]

Des méthodes pour les listes. Il existe de nombreuses méthodes pour les listes. En voici quelques
exemples :
1 >>> lis = [1,2,3,4,5,6,7,8,9,10]

— lis.count(x) : renvoie le nombre d’occurrences de x dans lis.


1 >>> lis. count (9)
2 1

— lis.reverse() : "retourne" (écrit à l’envers) la liste lis. Attention il s’agit d’une modification
physique : rien n’est renvoyé mais la liste lis est modifiée.
1 >>> lis. reverse ()
2 >>> lis
3 [10 , 9, 8, 7, 6, 5, 4, 3, 2, 1]

— lis.remove(x) : supprime physiquement la première occurrence de x dans lis. Si x n’apparaît


pas dans lis, l’instruction lis.remove(x) déclenche un message d’erreur.
1 >>> lis. remove (6)
2 >>> lis
3 [1, 2, 3, 4, 5, 7, 8, 9, 10]

— lis.sort() : modifie physiquement la liste lis pour la trier.


1 >>> l = [4,2,7,9,7]
2 >>> l.sort ()
3 >>> l
4 [2, 4, 7, 7, 9]

L’utilisation de l’instruction l.sort() suppose que les éléments de l soient issus d’un même type
ordonné.
1 >>> l = [1,’a’,[1,2]]
2 >>> l.sort ()
3 Traceback (most recent call last):
4 File "<pyshell #72 >", line 1, in < module >
5 l.sort ()
6 TypeError : ’<’ not supported between instances of ’str ’ and ’int ’

19
— lis.append : ajoute un élément à la fin de la liste lis. La différence par rapport à une instruc-
tion lis + [ x ] , est que c’est une modification physique, lis est modifiée et non simplement
recopiée avec un élément de plus à la fin.
1 >>> l=[2,3,4,5]
2 >>> l. append (4)
3 >>> l
4 [2,3,4,5,4]

— l1.extend(l2) : permet de rajouter les éléments de la liste l2 à la fin de la liste l1. Ceci modifie
physiquement la liste l1 et laisse la liste l2 inchangée. Cela revient à faire l1.append(t) pour
chaque élément t de la liste l2.
1 >>> l1 = [1,2,3]
2 >>> l2 = [4,5]
3 >>> l1. extend (l2)
4 >>> l1
5 [1, 2, 3, 4, 5]
6 >>> l2
7 [4, 5]

D’autres méthodes sont présentées dans la doc.

For en compréhension ! La syntaxe dune liste en compréhension est la suivante :


[ expression for var1, var2, ... vark in séquence ]
Cette expression construit la liste formée par les résultats des évaluations de expression obtenus en
donnant au tuple de variables (var1, var2, ... vark) successivement les valeurs de la séquence
indiquée. La partie ń for var1, var2, ... vark in séquence ż peut se répéter. Exemples pour
comprendre :
1 >>> t = (1, 2, 3, 4, 5) >>> [x for x in t]
2 [1, 2, 3, 4, 5]
3 >>> [x * x for x in t] [1, 4, 9, 16 , 25]
4 >>> [ x * y for x in t for y in t]
5 [1, 2, 3, 4, 5, 2, 4, 6, 8, 10 , 3, 6, 9, 12 , 15 , 4, 8, 12 , 16 , 20 , 5, 10 , 15 , 20
, 25]

Avec for, on peut fabriquer des listes très facilement : c’est le « for en compréhension » :
1 def carre (l):
2 return [x ** 2 for x in l]

1 >>> l = [2,3,4]
2 >>> [x ** 2 for x in l]
3 [4, 9, 16]

1 >>> l=[5, 8, 2, 1, 6, 9, 3]
2 >>> carre (l)
3 [25 , 64 , 4, 1, 36 , 81 , 9]
4 >>> l
5 >>> [5, 8, 2, 1, 6, 9, 3]

On peut ainsi créer des listes du genre :


“liste des truc(x) pour x dans une séquence et tels que machin(x)”.
Dans ce cas le programmateur n’a plus besoin d’écrire la boucle, elle se fait "seule" (mais bien en-
tendu, il y a une boucle). Cela peut être dans une fonction ou n’importe où dans un programme. On peut
par exemple extraire d’une liste la liste des entiers divisibles par 3 comme suit :

20
1 def extraire3 (l):
2 return [ y for y in l if y%3==0]
3 >>> extraire3 ([5,6,2,4,9,23 ,5,7,1,9])
4 [6,9,9]

On peut avoir plusieurs variables dans la même compréhension. Ainsi, si on représente un domino
comme une liste de deux éléments, chacun numéroté de 0 à 6, le script suivant crée la liste de tous les
dominos.
1 >>> cree_dom = [ [x,y] for x in range(0,7) for y in range (0,7) if x<=y]
2 # on met x<=y pour ne pas avoir [1,6] et [6,1]

Python gère très bien les listes de listes.

Le type list est un type séquentiel. À ce titre, toutes les fonctions définies sur les séquences sont
utilisables sur les listes :
(1) x in s : retourne True si l’élément x apparaît dans s, False sinon.
(2) x not in s : retourne True si l’élément x n’apparaît pas dans s, False sinon.
(3) s + t : retourne la concaténation des séquences s et t.
(4) n * s : retourne la concaténation de n copies de s.
(5) s [ i ] : retourne l’élément d’indice i dans s.
(6) s [ i : j ] : retourne la tranche de s des indices i à j - 1.
(7) s [ i : j : k ] : retourne la tranche de s des indices i à j par saut de k.
(8) len(s) : retourne le nombre d’éléments de s.
(9) s.index(x) : retourne l’indice de la première occurence de x dans s.
(10) min(s) : retourne le plus petit élément de s.
(11) max(s) : retourne le plus grand élément de s.
(12) s.count(x) : retourne le nombre d’occurences de l’élément x dans s.
(13) for x in s : provoque le parcours séquentiel des éléments de la séquence s par l’élément x.

Par ailleurs, le fait que list soit un type modifiable permet de faire agir des fonctions qui modifie
des listes prises en argument. Ces fonctions (qui ne sont pas définies pour les tuples et les chaînes de
caractères, par exemple) sont les suivantes :
(14) l [ i ] = x : remplace l’élément d’indice i de la liste l par la valeur de x.
(15) l [ i : j ] = l2 : remplace les éléments de la tranche l [ i : j ] par ceux de la liste l2.
(16) del l[i : j ] : supprime la tranche l [ i : j ] de l. (Même effet que l [ i : j ] = [ ] .)
(17) l.append(x) : ajoute l’élément x à la fin de l. (Même effet que l [ len(l):len(l)] = [ x ] .)
(18) l.extend(l2) : ajoute la liste l2 en fin de liste l. (Même effet que l [ len(l):len(l)] = l2.)
(19) l.insert(i,x) : insère l’élément x dans l à la position indiquée par l’indice i.
(20) l.remove(x) : retire la première occurence de x dans l.
(21) l.reverse() : renverse sur place les éléments de l.
Notons qu’il existe deux instructions pour ajouter un élément en fin de liste : liste + [ x ] et
liste.append(x). La première retourne une nouvelle liste construite à partir de liste en ajoutant
l’élément x sans modifier la liste initiale. La deuxième modifie la liste prise en entrée et ne retourne pas
de résultat.

21
6 Fichiers
6.1 Ouverture et clôture des fichiers
Les fichiers permettent de stocker des données, de les relire, de les partager. L’utilisation d’un fichier
en Python débute toujours par une instruction d’« ouverture », en « écriture » ou en « lecture » selon qu’on
s’apprête à y lire ou à y inscrire des données.

Ouverture en écriture. L’ouverture en écriture se fait grâce à l’instruction suivante :


1 >>> fic = open(" fichiertest ","a")

Le premier paramètre de la fonction open est le chemin d’accès (relatif ou absolu) au fichier. Par
exemple, ce pourrait être "essai.txt", ou "programmesPython/S2/tp2/essai.txt". Si le fichier
n’existe pas, il est créé avec ce nom. Le deuxième paramètre code la modalité d’ouverture :
— "a" pour ouvrir le fichier en mode ajout (ou append). Dans ce cas, les données sont ajoutées à la
fin du fichier.
— "w" pour ouvrir le fichier en mode write. Dans ce cas, le fichier est réinitialisé au moment de
l’ouverture s’il existait déjà (son ancien contenu est écrasé), ou créé s’il n’existait pas. Dans les
deux cas, les données inscrites seront mises au début de ce nouveau fichier vide.
La variable fic à gauche de l’affectation est ce qu’on appelle parfois un « nom logique » attribué au
fichier : c’est une variable que l’on associe au fichier physique (via la fonction open) et c’est sur elle, et
non sur le nom du fichier réel, que porteront toutes les fonctions ou méthodes de manipulation de fichier.
Par exemple, pour écrire dans ce « port » (c’est-à-dire dans ce fichier ouvert en écriture), on invoque
la méthode write de la manière suivante :
1 >>> fic. write (" bonjour tout le monde")
2 >>> fic. write ("au revoir à tous")

Les données sont alors écrites les unes à la suite des autres sans espace (sauf si on en rajoute).
Dans un fichier texte, on ne peut écrire que des chaînes de caractères. Si l’on veut y stocker des entiers
ou des listes, par exemple, il faut d’abord les encoder comme des strings. Par exemple, après l’ouverture
d’un fichier via l’instruction fic = open("f","w"), la tentative d’écrire des données de type autre que
str déclanche un message d’erreur :
1 >>> fic. write ([[1,2],[2,5]])
2 Traceback (most recent call last):
3 File "<pyshell #2>", line 1, in < module > fic. write (m)
4 TypeError : must be str , not list

1 >>> fic. write (5)


2 Traceback (most recent call last):
3 File "<pyshell #5>", line 1, in < module > fic. write (5)
4 TypeError : must be str , not int

Pour créer un fichier contenant les entiers de 1 à 9 on écrira par exemple :


1 f = open(" fichier_nombre ","w"):
2 for i in range (1,10):
3 f. write (str(i) + " ")
4 f. write ("fin")
5 f. close ( )

22
À l’issue de ces commandes, le fichier contient exactement : 1 2 3 4 5 6 7 8 9 fin
Pour conclure ce paragraphe, signalons que toute manipulation de fichier dans un programme se clôt
par une instruction de « fermeture » :
1 f. close ( )

C’est la condition pour que toutes les modifications apportées au fichier soient réellement enregistrées ;
c’est aussi le moyen de rendre le fichier disponible pour toute nouvelle utilisation.

Ouverture en lecture. On ouvre un fichier en lecture lorqu’on souhaite y lire des données. Ceci se fait
toujours avec la fonction open mais avec "r" (comme read) en deuxième paramètre.
1 >>> f = open(" fichier_nombre ","r")
2 >>> truc = f.read ()
3 >>> truc
4 ’1 2 3 4 5 6 7 8 9 fin ’

Comme on n’a pas mis d’argument à read, le fichier est lu dans son intégralité et la chaîne de carac-
tères correspondante est renvoyée. On peut aussi mettre en argument de la fonction read le nombre de
caractères à lire. Ce nombre est compté à partir de la position actuelle dans le fichier. Si on reprend le
fichier nommé fichier_nombre :
1 >>> lect = open(" fichier_nombre ","r")
2 >>> t1 = lect.read(8)
3 >>> t1
4 ’1 2 3 4 ’
5 >>> t2 = lect.read(6)
6 >>> t2
7 ’5 6 7 ’
8 >>> t3 = lect.read(14)
9 >>> t3
10 ’8 9 fin ’
11 >>> t4 = lect.read(1)
12 >>> t4
13 ’’

On voit que le deuxième read commence la lecture là où s’est arrêté le premier read. S’il ne reste
pas assez de caractères alors le read s’arrête à la fin du fichier (sans erreur). Si on était déjà à la fin du
fichier c’est une chaîne vide qui est renvoyée.
Comme après les manipulations d’écriture, il faut impérativement fermer un fichier après son utilisa-
tion en lecture. C’est à nouveau l’instruction l.close() qui provoque cette fermeture. Insistons encore
sur l’enjeu qu’il y a à bien fermer les fichiers à l’issue de chacune de leur utilisation :
1. le nombre de fichiers simultanéments ouverts est limité.
2. Python ne garantit pas que les données écrites le soient vraiment tant que le fichier n’a pas été
fermé proprement.
3. Si d’autres applications, ou d’autres morceaux de votre propre code tentent douvrir un fichier qui
na pas été fermé, l’accès leur en sera interdit.

6.2 Exemple de programmes avec des fichiers


Comparaison de fichiers. La fonction suivante teste l’identité de deux fichiers. Elle renvoie True si
les fichiers sont identiques, ou les premiers caractères distincts si les fichiers diffèrent.

23
1 def compare (fic1 ,fic2):
2 f1 = open(fic1 ,"r")
3 f2 = open(fic2 ,"r")
4 while 1:
5 x1 , x2 = f1.read(1), f2.read(1)
6 if x1 != x2:
7 f1. close ( )
8 f2. close ( ) # fermer les fichiers avant le return
9 return x1 , x2
10 if x1 == "" : # si on arrive à la fin de fichier pour les 2 fichiers
11 f1. close ( )
12 f2. close ( )
13 return True

Remarque : La boucle while ci-dessus est un peu particulière puisque la condition de sortie de boucle,
« 1 », reste toujours vraie. L’exécution d’une telle boucle est donc a priori infinie ! Dans les faits, la
boucle termine quels que soient les fichiers pris en entrée puisque son exécution provoque nécessairement
l’exécution d’une instruction return au bout d’un nombre fini d’étapes.
Dans les parcours de fichiers on rencontre souvent ce genre de boucle, avec une condition invariable
et une sortie de boucle provoquée par la rencontre d’un caractère particulier ou de la fin de fichier. La
sortie de boucle est alors forcée par une instruction break ou return.

Copie de fichiers. La fonction suivante prend deux fichiers en arguement et recopie le contenu du
premier dans le second, caractère par caractère :
1 def recopie (source , but):
2 f1= open(source , "r")
3 f2 = open(but , "w")
4 while 1:
5 x1 = f1.read(1)
6 if x1 == "": # teste la fin du fichier
7 f1. close ( )
8 f2. close ( )
9 break # il n’y a rien à retourner
10 else:
11 f2. write (x1)

Ici, la sortie de boucle advient quand le test x1 == "" est validé, c’est-à-dire quand la fin de fichier
est rencontrée. (Ne confondez pas avec la condition x1 == " " qui est validée chaque fois que l’on
rencontre un espace dans le fichier.)

6.3 Résumé des fonctions et méthodes utiles


(1) fic = open("fichier","r") : ouvre le fichier fichier en lecture et lui attribue le nom logique
fic.
(2) fic = open("fichier","w") : ouvre le fichier fichier en écriture et lui attribue le nom logique
fic. Le mode w a pour effet d’écraser le contenu du fichier dès l’ouverture.
(3) fic = open("fichier","a") : ouvre le fichier fichier en écriture et lui attribue le nom logique
fic. Le contenu du fichier est préservé et les chaîne écrites dans le fichier le seront en bout de fichier.
(4) fic.read() : retourne une chaîne de caractère contenant l’intégralité du fichier. Nécessite que le
fichier soit ouvert en lecture.
(5) fic.read(n) : Retourne une chaîne contenant les n caractères du fichier qui suivent la position de
la tête de lecture. Nécessite que le fichier soit ouvert en lecture.

24
(6) fic.readline() : Retourne une chaîne contenant tous les caractères du fichier entre la position
de la tête de lecture et le prochain caractère de fin de ligne. Nécessite que le fichier soit ouvert en
lecture.
(7) fic.readlines() : Retourne la liste des lignes du fichier. Nécessite que le fichier soit ouvert en
lecture.
(8) fic.write(chaine) : ajoute la chaîne de caractère chaine à la fin du fichier fic. Nécessite l’ou-
verture du fichier en écriture.
(9) for l in fic : Crée une variable l de type str et lui fait parcourir l’ensemble des lignes du fichier.
Nécessite l’ouverture du fichier en lecture.
(10) s.split() : retourne une liste construite à partir de la chaîne de caractères s en séparant les sous-
chaînes de s encadrées par des espaces.
(11) s.split(c) : retourne une liste construite à partir de la chaîne de caractères s en séparant les
sous-chaînes de s encadrées par le caractère c.

25
7 Dictionnaires
La dernière section de ce cours est consacrée à un nouveau type de données : les dictionnaires, dési-
gnés par le mot réservé dict. Il s’agit à nouveau d’un type composite, permettant comme les listes ou les
tuples de coaliser plusieurs composants dans un même objet, ces composants pouvant quant à eux être de
types divers. Mais à l’inverse des listes et des tuples, les dictionnaires ne sont pas des séquences : leurs
éléments constitutifs ne sont pas indicés. C’est d’ailleurs tout l’intérêt des dictionnaires : les éléments
d’un dictionnaire sont bien "repérés" par une clé, qui permet de les retrouver facilement, ou de parcou-
rir le dictionnaire, mais cette clé n’est pas nécessairement un entier. En quoi est-ce utile ? Imaginez par
exemple une base de donnée permettant de stocker des morceaux de musique et des informations qui
leurs sont attachées : titre, interprète, année de création, label, etc. Organiser une telle base sous forme de
liste impose, dès qu’on lance une requête sur un morceau particulier — quel est son interprète ? sa date
de création ? — de se souvenir de son indice dans la liste. Ceci devient vite impossible au fur et à mesure
que la liste s’accroît. À l’inverse, si l’on a pris soin de repérer chaque morceau par un code unique — ce
qu’on appelera bientôt sa clé — et si les données sont organisées de sorte que l’accès à un élément à partir
de sa clé soit facile, alors on pourra facilement gérer de grosses mases de données.
C’est à cela que servent les dictionnaires en Python. L’exemple le plus typique, qui justifie le nom de
ce type de données, c’est précisément celui du dictionnaire. Pour constituer un dictionnaire anglo-français,
par exemple, on veut mettre en vis à vis des mots anglais et leurs traductions françaises. Le bon moyen
de faire ça, c’est de stocker les traduction françaises en les « indexant » non pas par un entier, mais par
le mot anglais qu’elles traduisent. Ceci permettra non seulement de trouver facilement la traduction en
français d’un mot anglais (en y accédant à partir de sa clé, c’est-à-dire via le mot anglais correspondant)
mais en plus, ça permettra d’ajouter de nouveaux mots à ce stockage sans se préoccuper de leur rang dans
le stock déjà constitué.
Un tel dictionnaire pourra être initialisé par une affectation de la forme :
1 >>> dico = {’apple ’:’pomme ’, ’chair ’:’chaise ’, ’plate ’:’assiette ’}

Un dictionnaire est en effet un ensemble de couples composés d’une clé et de la valeur à laquelle elle
permet d’accéder. Les couples sont déclarés entre accolades, séparés par des virgules, et sous la forme
clé:valeur plutôt que (clé,valeur). De plus les clés comme les valeurs peuvent être de n’importe
quel type, et pas seulement du type str utilisé dans l’exemple qui nous occupe. Une contrainte doit
être respectée : l’unicité de la valeur référée par chaque clé. Autrement dit, un dictionnaire ne peut pas
comporter deux couples de la forme clé:valeur1 et clé:valeur2 dans lesquels valeur1 et valeur1
sont deux valeurs distinctes. Si une telle situation se produit, le dernier appariement de clé fixée écrasera
les précédents :
1 >>> dic = {1:’a’, 2:’b’, 1:’c’, 3:’aa ’, 1:’xy ’}
2 >>> dic
3 {1: ’xy’, 2: ’b’, 3: ’aa’}

L’unicité de la clé associée à chaque valeur permet d’extraire une valeur du dictionnaire à partir de
sa clé. Ainsi, de même que l’expression lis[i ] permet d’accéder à l’élément d’indice i dans une liste
lis, l’expression dico[c ] permet d’accéder à la valeur de clé c dans un dictionnaire dico.
1 >>> dico[’plate ’]
2 ’assiette ’

Le type dict est mutable : on peut modifier « physiquement » un objet de ce type. On peut par
exemple associer une clé existante à une nouvelle valeur via l’instruction dico[clé] = valeur :
1 >>> dico[’apple ’]=’poire ’
2 >>> dico
3 {’apple ’: ’poire ’, ’chair ’: ’chaise ’, ’plate ’: ’assiette ’}

26
Si la clé utilisée n’apparaissait pas dans le dictionnaire initial, cette instruction a pour effet de créer
un nouveau couple clé:valeur dans le dictionnaire :
1 >>> dico[’mouse ’] =’souris ’
2 >>> dico
3 {’apple ’: ’poire ’, ’chair ’: ’chaise ’, ’plate ’: ’assiette ’, ’mouse ’: ’souris ’}

D’ailleurs, nous aurions pu initialiser dico de cette manière :


1 >>> dico = {} # dictionnaire vide
2 >>> dico[’apple ’] = ’pomme ’
3 >>> dico[’chair ’] = ’chaise ’
4 >>> dico[’plate ’] = ’assiette ’
5 >>> dico
6 {’apple ’:’pomme ’, ’chair ’:’chaise ’, ’plate ’:’assiette ’}

Pour retirer un couple clé-valeur d’un dictionnaire, on utilise la fonctiondel : si dic contient un
couple clé:valeur, l’instruction del dic[clé] retire ce couple du dictionnaire.
1 >>> dico
2 {’apple ’: ’poire ’, ’chair ’: ’chaise ’, ’plate ’: ’assiette ’, ’mouse ’: ’souris ’}
3 >>> del dico[’apple ’]
4 >>> dico
5 {’chair ’: ’chaise ’, ’plate ’: ’assiette ’, ’mouse ’: ’souris ’}

La fonction print affiche le dictionnaire à l’écran. Sur l’interpréteur, le résultat est le même que celui
obtenu en tapant le nom du dictionnaire (mais on sait que si ce nom est tapé tel quel dans le corps d’une
fonction, il ne provoque aucun affichage).
1 >>> print (dico)
2 {’chair ’: ’chaise ’, ’plate ’: ’assiette ’, ’mouse ’: ’souris ’}

L’expression cle in dico est évaluée à True si la clé cle apparaît dans dico, et à False sinon.
Par ailleurs, une instruction de la forme :
1 >>> for cle in in dico:
2 ...

a pour effet de faire parcourir l’ensemble des clés de dico à la variable cle. Par exemple, on pourra
utiliser cette boucle pour afficher les clés ou les valeurs de dico :
1 >>> for cle in dico:
2 print(cle)
3 chair
4 plate
5 mouse

1 >>> for cle in dico:


2 print(dico[cle])
3 chaise
4 assiette
5 souris

Du fait qu’ils ne sont pas des séquences, les dictionnaires se révèlent donc particulièrement précieux
pour gérer des ensembles de données où l’on est amené à effectuer fréquemment des ajouts ou des sup-
pressions, dans n’importe quel ordre. Ils remplacent avantageusement les listes lorsqu’il s’agit de traiter
des ensembles de données numérotées, dont les numéros ne se suivent pas.

27
Résumé des fonctions et méthodes utiles
(1) dic = {c1:v1,..., ck:vk : initialise le dictionnaire dic avec les couples c1 : v1, . . . , ck : vk.
(2) dic[cle] : retourne la valeur associée à la clé cle dans dic. (Message d’erreur si cle n’apparaît
pas dans dic.)
(3) dic[cle] = val : remplace la valeur associée à cle dans dic par la nouvelle valeur val ; si cle
n’apparaissait pas dans dic, ajoute le nouveau couple cle:val à dic.
(4) del dic[cle] : supprime le couple de clé cle dans dic. (Erreur si ce couple n’existe pas.)
(5) print(dic) : affiche tous les couples de dic.
(6) cle in dic : retourne True si la clé cle apparaît dans dic, False sinon.
(7) for cle in dic : contraint la variable cle à parcourir l’ensemble des clés apparaissant dans dic.

Exemples de scripts. La fonction suivante compte le nombre d’occurrences des caractères d’une chaîne
prise en entrée et retourne le résultat dans un dictionnaire dont chaque couple est de la forme c : n où c
est un caractère apparaissant dans s et n est son nombre d’occurrences.
1 def compte_car (s):
2 dico = {}
3 for c in s:
4 if c in dico:
5 dico[c] += 1
6 else:
7 dico[c] = 1
8 return dico

1 >>> compte_car (" abracadabra ")


2 {’a’: 5, ’b’: 2, ’r’: 2, ’c’: 1, ’d’: 1}

28

Vous aimerez peut-être aussi