Vous êtes sur la page 1sur 111

Fondamentaux de la

programmation
en Python
IUT Réseaux &
Télécommunications
1reannée

Éric Würbel
Copyright © 2019–2023 Éric Würbel

Cette oeuvre, création, site ou texte est sous licence Creative Commons Attribution - Pas d’Utili-
sation Commerciale - Partage dans les Mêmes Conditions 4.0 International. Pour accéder à une
copie de cette licence, merci de vous rendre à l’adresse suivante http://creativecommons.org/
licenses/by-nc-sa/4.0/ ou envoyez un courrier à Creative Commons, 444 Castro Street, Suite
900, Mountain View, California, 94041, USA.
Table des matières

I Généralités
1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.1 Programmation 11
1.2 Le langage Python 13
1.2.1 Historique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.2.2 Un langage de programmation multi-paradigmes . . . . . . . . . . . . . . . . . . . . . . 13
1.2.3 Usages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2 Objectifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
2.1 Objectifs thématiques 15
2.2 Objectifs pédagogiques 15
2.3 Objectifs comportementaux 16

II Le langage Python

3 Instructions de base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.1 Introduction 19
3.2 Variables & Affectation 19
3.2.1 Qu’est-ce qu’une variable ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2.2 Type d’une variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.2.3 Attribuer une valeur : l’affectation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.2.4 Conversions de type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.3 Expressions 24
3.3.1 Définitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.3.2 Constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.3.3 Expressions simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.3.4 Expressions unaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
3.3.5 Expressions multiplicatives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.3.6 Expressions additives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.3.7 Expressions de décalage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
3.3.8 Expression booléennes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
3.3.9 Exercices sur les expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
3.4 Affectation composée 35
3.5 Entrées et sorties simples 36
3.5.1 Sorties à l’écran . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
3.5.2 Entrées au clavier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3.6 Modules, fonctions et méthodes 38
3.6.1 Présentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.6.2 Caractéristiques et appel d’une fonction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.6.3 Méthodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.7 Annexes 41
3.7.1 Solutions des exercices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

4 Structures alternatives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.1 Alternative simple : si. . . alors. . . sinon. . . 45
4.2 Condition simple : si. . . 47
4.3 Alternatives multiples : si. . . sinon si. . . sinon. . . 48
4.4 Structures alternatives : bilan 50
4.5 Annexes 51
4.5.1 Solutions des exercices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51

5 Structures répétitives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
5.1 Principes généraux 53
5.2 Itération conditionnelle : la boucle while 53
5.3 La boucle for 55
5.3.1 Le compteur d’itérations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
5.3.2 Répétition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.3.3 Répétition utilisant le compteur de boucle . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.3.4 Valeur initiale du compteur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.3.5 Incrément du compteur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
5.4 Équivalence entre boucle for et boucle while 59
5.5 Boucles et structures alternatives 60
5.6 Boucles avec variables d’accumulation 60
5.6.1 Principe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
5.6.2 Accumulation additive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
5.6.3 Accumulation multiplicative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
5.7 Imbrication de boucles 63
5.8 Exercices supplémentaires sur les boucles 63
5.9 Annexes 64
5.9.1 Solutions des exercices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64

6 Procédures et fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
6.1 Définition 69
6.2 Déclaration d’une fonction 69
6.3 Fonctions à plusieurs points de retour 72
6.4 Portée des variables 74
6.4.1 Notion de portée . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
6.4.2 Contexte local d’une fonction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
6.4.3 Contexte d’une fonction avec paramètres . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
6.5 Chaînage de fonctions 76

7 Listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
7.1 Les listes 77
7.2 Accès aux éléments 78
7.2.1 Éléments et indices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
7.2.2 L’opérateur in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
7.3 Fonctions et méthodes pour l’objet list 80
7.3.1 Méthodes modifiant les éléments d’une liste . . . . . . . . . . . . . . . . . . . . . . . . . . 80
7.3.2 Méthodes utilisant les éléments d’une liste . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
7.3.3 Fonctions sur les listes numériques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
7.3.4 Autres méthodes sur les listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.4 Parcours de listes 82
7.4.1 Notion d’itérable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.4.2 Parcours itératif de tous les éléments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
7.4.3 Parcours d’une partie des éléments avec une boucle while . . . . . . . . . . . . . . 85
7.5 Construire une liste 85
7.5.1 utilisation de append . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
7.5.2 Opérateurs sur les listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.5.3 Fonction range . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.5.4 Liste en intention . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.6 Listes et fonctions 87
7.7 Listes en deux dimensions 88
7.8 Exercices supplémentaires 88
7.9 Annexes 89
7.9.1 Solutions des exercices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89

8 Chaînes de caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
8.1 Le type str 99
8.2 Accès aux caractères 99
8.2.1 Caractères et indices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
8.2.2 L’opérateur in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
8.3 Manipulation de chaînes de caractères 101
8.3.1 rappel : manipulations élémentaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
8.3.2 Méthodes de la classe str . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
8.4 Parcours de chaînes de caractères 103
8.4.1 Parcours itératif avec une boucle for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
8.4.2 Parcours itératif avec une boucle while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
8.5 Construction itérative d’une chaîne 105
8.6 Constantes du module string 106

9 Entrées-sorties sur des fichiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107


9.1 Définitions 107
9.2 Principes d’accès aux fichiers 108
9.3 Ouverture et fermeture d’un fichier texte 108
9.4 Gestionnaire de contexte 109
9.4.1 Lecture de fichiers texte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
9.4.2 Écriture dans un fichier texte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
9.4.3 Positionnement du pointeur d’accès . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
Préface

Cet ouvrage est un manuel d’apprentissage du langage de programmation Python destiné aux
étudiants de 1re année de BUT Réseaux & Télécommunications de l’IUT d’Aix-Marseille Université.
Il couvre les apprentissages à acquérir dans la ressource R107 Fondamentaux de la programmation.
Ce module est consacré à l’apprentissage de l’algorithmique et du langage de programmation
Python. Du fait du nombre d’heures consacrées à cette ressource, il ne saurait être question de
faire d’abord de l’algorithmique sans langage de programmation, puis d’étudier la traduction des
algorithmes dans un langage de programmation. Aussi l’apprentissage de l’algorithmique se fera
directement en s’appuyant sur le langage Python.
Les contenus suivants seront traités :
— Notions d’algorithmique :
— Variables, types de base : nombres, chaînes, booléens, et un unique type structuré : les
listes ;
— Structures de contrôle : structures alternatives et structures itératives ;
— Fonctions & procédures ;
— Portée des variables.
— Structures de données : chaînes de caractères, listes, piles et files.
— Tests de correction d’un programme (tests unitaires, tests d’intégration) (vu en TP).
— Prise en main d’un environnement de programmation (éditeur, environnement de développe-
ment) (vu en TP).
— Prise en main de bibliothèques, modules, d’objets existants (appels de méthodes).
— Manipulation de fichiers texte.
— Interaction avec le système d’exploitation et la ligne de commande : arguments, lancement
de commandes (vu en TP).
Le contenu de ce manuel s’inspire énormément des supports suivants :
— Le cours d’initialition à la l’algorithmique de l’école nationale d’ingénieurs de Brest ;
— les supports de cours des collègues du département Réseaux & Télécommunications de l’IUT
de Grenoble.
Il s’inspire aussi de l’ancienne version de ce manuel traitant de l’ancien module M1207.
I
Généralités

1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 11

2 Objectifs . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1. Introduction

1.1 Programmation
Un algorithme exprime la structure logique d’un programme, et est donc indépendant du
langage de programmation utilisé. En revanche, la traduction de l’algorithme vers un langage de
programmation particulier dépend du langage choisi, et la mise en œuvre dépend de la plateforme
d’exécution.
La programmation consiste à « expliquer » en détail à l’ordinateur ce qu’il a à faire, sachant qu’il
ne « comprend » pas le langage humain, mais peut uniquement effectuer un traitement automatique
sur des séquences de 0 et de 1. Un programme n’est rien d’autre qu’une suite d’instructions, codées
en respectant scrupuleusement un ensemble de conventions fixées à l’avance 1 par un langage de
programmation. La machine décode alors ces instructions en associant à chaque « mot » du langage
de programmation une action précise. Le programme écrit dans le langage de programmation (à
l’aide d’un éditeur, sorte de traitement de texte spécialisé) est appelé programme source (ou code
source).
Le seul langage que l’ordinateur « comprenne » vraiment est très éloigné de ce que nous
comprenons nous même : c’est une longue suite de 0 et de 1 (les bits, binary digit), traités par
groupes de 8 (les octets, ou byte en anglais), 16, 32 ou même 64. Ce langage composé d’informations
binaires est appelé langage machine.
Définition 1.1.1 — bit. Un bit est un chiffre binaire (0 ou 1). C’est l’unité élémentaire d’infor-
mation.

Définition 1.1.2 — octet. Un octet est une unité d’information composée de 8 bits.

Pour se faire comprendre d’un ordinateur, il faudra donc faire appel à un système de traduction
automatique, capable de convertir en nombres binaires les suites de caractères formant le code
source d’un programme. Il existe deux grands types de systèmes de traduction (figure 1.1) :

1. L’ensemble de ces règles est appelé syntaxe du langage de programmation. On peut comparer la syntaxe d’un
langage de programmation à la grammaire d’une langue naturelle.
12 Chapitre 1. Introduction

Définition 1.1.3 — compilateur. Un compilateur est un programme qui traduit un langage, le


langage source, en un autre langage, le langage cible.

Définition 1.1.4 — interpréteur. Un interpréteur est un programme ayant pour tâche d’analyser
et d’exécuter un programme écrit dans un langage source.

compilation interprétation semi-compilation


ADA, C, Rust Lisp, Prolog, Java, Python,
C++, Fortran PHP, Javascript Scheme, Scala

code source code source code source

compilateur compilateur

code objet interpréteur bytecode

exécuteur interpréteur

résultat résultat résultat

F IGURE 1.1 – Du code source à son exécution

On appellera langage de programmation un ensemble de mots-clés et une ensemble de règles


précises indiquant comment agencer ces mots pour former des « phrases » que l’interpréteur ou le
compilateur puisse traduire en langage machine. Un langage de programmation se distingue du
langage mathématique par son objectif opérationnel (c’est-à-dire qu’il doit être exécutable par la
machine).
Définition 1.1.5 — langage de programmation. Un langage de programmation est un
langage informatique permettant à un humain d’écrire du code source qui sera analysé puis
exécuté par un ordinateur.

Le code source subit alors une transformation (dans le cas du compilateur) ou une évaluation
(dans le cas de l’interpréteur) dans une forme exploitable par la machine, ce qui permet d’obtenir
un programme. Les langages de programmation permettent de faire abstraction des mécanismes de
bas niveau de la machine, de sorte que le code source soit lisible et compréhensible par un humain.
Définition 1.1.6 — programmation. La programmation est l’activité de rédaction du code
source d’un programme.

Compilation : La compilation consiste à traduire la totalité du code source d’un programme en


une seule fois. Le compilateur lit toutes les lignes d’un programme source et produit une
nouvelle suite de codes appelée programme objet (ou code objet). Celui-ci peut être exécuté
indépendament du compilateur et être conservé dans un fichier appelé fichier exécutable.
Les langages A DA, Rust, C, C++, Fortran sont des exemples de langage de programmation
utilisant le mécanisme de la compilation.
Interprétation : L’interprétation consiste à traduire chaque ligne du programme source en quelques
1.2 Le langage Python 13

instructions en langage machine, qui sont directement exécutées au fur et à mesure (au fil
de l’eau). Aucun programme objet n’est généré. L’interpréteur doit être utilisé à chaque fois
qu’on veut exécuter le programme. Les langages L ISP et P ROLOG sont des exemples de
langages de programmation interprétés 2 . Les langages du W EB PHP et Javascript sont aussi
des langages interprétés.
L’interprétation est idéale lorsqu’on est en phase d’apprentissage du langage, ou en cours
d’expérimentation sur un projet. Elle permet de tester immédiatement une modification
apportée au programme source, sans passer par une phase de compilation qui peut prendre du
temps. En revanche, lorsqu’un programme atteint un certain degré de complexité, et qu’il doit
s’exécuter rapidement, la compilation est plus efficace : un programme compilé s’exécutera
toujours plus vite qu’un programme interprété, puisque l’ordinateur ne perd pas de temps à
refaire la traduction de chaque instruction exécutée.
Semi-compilation : Certains langages utilisent les deux techniques précédentes pour tenter d’en
tirer le meilleur parti. C’est le cas de P YTHON et JAVA par exemple. De tels langages
commencent par compiler le code source pour produire un code intermédiaire, similaire à
un langage machine, mais pour une machine virtuelle, qu’on appelle bytecode. Ce bytecode
sera alors transmis à un interpréteur (qu’on appelle machine virtuelle dans ce cas) à chaque
exécution. Du point de vue de l’ordinateur, le bytecode est très simple à interpréter en langage
machine.
Le fait de disposer en permanence d’un interpréteur permet de tester n’importe quel petit
morceau de programme. On pourra donc vérifier le bon fonctionnement de chaque composant
d’une application au fur et à mesure de son développement. L’interprétation du bytecode
compilé n’est pas aussi rapide que l’exécution directe de code machine, mais elle est très
satisfaisante pour de nombreux programmes. De plus, les machines virtuelles font des
progrès constants qui tendent à rapprocher les performances d’interprététion du bytecode de
l’exécution native de code machine.
Interprétation, compilation, semi-compilation, toutes ces techniques s’occupent toutes du même
problème : traduire en instructions compréhensibles par l’ordinateur des instructions écrites dans
un autre langage.

1.2 Le langage Python


1.2.1 Historique
La conception de Python remonte à la fin des années 80. Le développeur Guido van Rossum,
qui travaillait dans l’équipe de développement du système d’exploitation réparti Amoeba, estime
qu’un langage de scripting inspiré du langage ABC pourrait être intéressant, les appels systèmes
d’Amoeba étant difficilement interfaçable en utilisant un shell de type Unix. Il écrit une première
version du langage durant une semaine de vacances. Il baptise ce langage Python en référence à la
troupe comique britanique Monty Python 3 .
Dans L’année qui suit, le langage est adopté par l’équipe de développement d’Amoeba.

1.2.2 Un langage de programmation multi-paradigmes


Python est un langage appartenant à la famille des langages de programmation orientés objets.
Cela signifie que tout composant du langage est vu comme un objet contenant des données (données
membres) et pouvant effectuer des traitements reflétant son comportement (méthodes). Nous verrons

2. Quoi qu’il existe des versions de L ISP et P ROLOG utilisant la semi-compilation.


3. Cela explique aussi la présence envahissante de spam dans les exemples illustrant la documentation python, ainsi
que parfois ce document.
14 Chapitre 1. Introduction

que tous les types de données de Python sont des objets. Cette notion sera précisée lorsque nous
étudierons quelques unes des nombreuses bibliothèques fournies par Python.
Python emprunte aussi certaines constructions à la programmation fonctionnelle, dans laquelle
la structuration des traitements et des données s’appuie sur la notion de fonction. Nous y reviendrons
aussi.

1.2.3 Usages
Le langage Python est polyvalent et ses usages sont multiples : cela va de l’application de
bureau à l’utilitaire système, en passant par des applications scientifiques. C’est un très bon langage
de scripting, c’est à dire qu’il peut être très utile à l’administrateur système : il est plus simple que
le shell et mieux structuré. Aujourd’hui, Python est souvent choisi comme langage de scripting
pour les équipements réseaux comme les routeurs, d’où son importance pour vous.
2. Objectifs

2.1 Objectifs thématiques

Ce document couvre le contenu de la ressource R107 (Bases de la programmation) et les


compléments nécessaires au module R208 (Analyse et traitement de données structurées), plus
quelques notions non abordées en cours mais qui peuvent être utiles.

2.2 Objectifs pédagogiques

Pour décrire la situation des différentes activités de ce module par rapport aux outils pédago-
giques associés, je reprendrai la métaphore musicale utilisée dans l’excellent cours d’algorithmique
de l’ENIB .
Pédagogie par objectifs : Le solfège est l’étude des principes élémentaires de la musique et de
sa notation et chaque exercice a un objectif précis pour évaluer l’apprentissage du langage
musical. Il en va de même pour l’informaticien débutant confronté à l’apprentissage d’un
langage de programmation.
Pédagogie par l’exemple : L’apprentissage de pièces de musique permet au musicien de s’appro-
prier les bases du solfège en les appliquant à ces partitions et en les (re)jouant lui-même.
L’informaticien débutant, en (re)codant lui-même des algorithmes bien connus, se constituera
ainsi une base de réflexes de programmation en « imitant » ces algorithmes.
Pédagogie de l’erreur : Les bogues (bugs) sont à l’informaticien ce que les fausses notes sont aux
musiciens : des erreurs. Ces erreurs sont nécessaires dans l’acquisition de la connaissance.
Un élève a progressé si, après s’être trompé, il peut reconnaître qu’il s’est trompé, dire où et
pourquoi il s’est trompé, et comment il recommencerait sans produire les mêmes erreurs.
Pédagogie par problèmes : Connaissant ses classiques et les bases du solfège, le musicien de-
venu plus autonome peut envisager sereinement la création de ses propres morceaux. Le
développement d’un projet informatique ambitieux sera « mis en musique » au semestre S2.
16 Chapitre 2. Objectifs

2.3 Objectifs comportementaux


Les qualités comportementales attendues d’un développeur, et que nous développerons dès ce
module, sont :
Rigueur : Un langage de programmation obéit à des règles très précises. Un simple oubli de
ponctuation peut provoquer l’échec de la compilation (ou de l’interprétation). De même,
dans un algorithme, l’inversion de deux étapes peut conduire à un résultat faux. Bref, en
algorithmique comme en programmation, on ne saurait se contenter d’à peu près. Deux
exemples pour illustrer ces deux aspects :
Exemple 2.1 — Erreur de syntaxe en Python. Le programmeur a oublié un caractère
':' la ligne 3 du fichier source Test.py. Le compilateur signale l’erreur.

File "Test.py", line 3


while a < 5
^
SyntaxError: invalid syntax

Un être humain peut parfaitrement passer outre l’absence de caractère ':'. Cela ne l’empêche
pas de comprendre le sens. La machine elle se sait pas faire cela. Elle ne se contente pas d’à
peu près, elle exige un strict respect des règles d’écriture (de la grammaire) du langage. 
Persévérance Devant les messages d’erreur d’un compilateur, le débutant est souvent tenté de
« passer à autre chose », d’autant qu’il a parfois du mal à comprendre le sens des messages
d’erreur. Ce comportement ne mène à rien de bon, et il est important de prendre l’habitude
de ne pas laisser de problème en suspens. Il faut donc que le débutant apprenne à aller au
fond des choses et à traiter complètement un problème lorsqu’il se présente.
Autonomie Programmer les algorithmes qu’on a développé, mais aussi faire la trace (même
manuelle) de ces algorithmes pour en comprendre tout le sens est la meilleure école d’ap-
prentissage. Elle nécessite de se prendre en charge, d’apprendre à identifier ses erreur et à
trouver des solutions pour les corriger. Cela nécessite une grande autonomie dans son travail.
II
Le langage Python

3 Instructions de base . . . . . . . . . . . . . . . . . 19

4 Structures alternatives . . . . . . . . . . . . . . . 45

5 Structures répétitives . . . . . . . . . . . . . . . . . 53

6 Procédures et fonctions . . . . . . . . . . . . . . 69

7 Listes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77

8 Chaînes de caractères . . . . . . . . . . . . . . 99

9 Entrées-sorties sur des fichiers . . . . . . . 107


3. Instructions de base

3.1 Introduction
Comme il a été dit dans le chapitre introductif, un algorithme est une suite ordonnée d’instruc-
tions qui indique la démarche à suivre pour résoudre un ensemble de problèmes équivalents. Quand
on définit un algorithme, les instructions le composant doivent être compréhensible par l’ordinateur.
Dans ce chapitre, nous nous intéresserons aux instructions (statements) de base de l’algo-
rithmique telles qu’elles existent dans un langage de haut niveau comme Python. Il s’agit de
l’affectation (assignment), des appels de fontions (function call), des expressions utilisables dans le
contexte de ces instructions de base et d’autres instructions que nous verrons par la suite, et des
instructions d’entrée au clavier (keyboard input)et de sortie à la console (console output).

3.2 Variables & Affectation


3.2.1 Qu’est-ce qu’une variable ?
 Exemple 3.1 — Conversion de température. Le degré Farenheit (◦ F) est une unité de mesure
de la température. Dans cette échelle de mesure, le point de solidification de l’eau est de 32 degrés,
et son point d’ébulition de 212 degrés. Ainsi par exemple 70◦ F correspondent approximativement
à 21◦C. 

Pour effectuer la conversion Farenheit → Celsius, nous commençons par donner un nom à la
température en degrés Farenheit, par exemple tF , ainsi qu’à la température en degrés Celsius, par
exemple tC . Puis nous exprimons la relation liant ces deux températures : tC = 59 (tF − 32). Nous
pouvons appliquer cette relation à un cas particulier, par exemple tF = 70 : tC = 59 (70 − 32) ≈ 21.
En informatique, l’essentiel du travail effectué par un programme consiste à manipuler des
données stockées dans la mémoire centrale (voir le cours d’architecture des ordinateurs). Ces
données peuvent être très diverses (par exemple des températures), et il est pratique de nommer ces
données plutôt que de connaître directement leurs adresses en mémoire.
Ainsi, les données sont désignées par un nom de variable (par exemple tC ou tF : on dit que
la variable désigne (ou dénote) une valeur. Pour la machine, il s’agit d’une référence désignant
20 Chapitre 3. Instructions de base

une adresse mémoire, c’est à dire un emplacement précis dans la mémoire vive où est stockée une
valeur.
Précisons ce qu’est une variable au sens de Python.
Définition 3.2.1 — variable. Une variable désigne un objet informatique dans une zone
mémoire. Elle :
1. est désignée par un identificateur, appelé aussi nom, lié à une référence (donc un espace
mémoire)
2. mémorise une valeur, évoluant avec le flot d’instructions mais unique à un instant donné
3. présente un type, précisant la nature de la valeur qu’elle mémorise

Définition 3.2.2 — Noms des variables. Un identificateur de variable :


— commence par une lettre ;
— peut comprendre des lettres, des chiffres ou le caractère _
— ne doit pas être un des mots réservés suivants :
and del from not while
as elif global or with
assert else if pass yield
break except import print
class exec in raise
continue finally is return
def for lambda try

On peut résumer ces règles par le diagramme suivant.

 
hidentificateuri : :=-
- hlettrei    -
 hchiffrei 
 hlettrei 
 ‘_’ 

 Exemple 3.2 — identificateurs de variables.


— x est un identificateur de variable valide.
— nb_passages est un identificateur de variable valide.
— id2 est un identificateur de variable valide.
— 3fois n’est pas un identificateur de variable valide (car il commence par un chiffre).
— _ n’est pas un identificateur de variable valide (car il commence par un caractère _).
— _racine2 n’est pas un identificateur de variable valide (car il commence par un caractère _).


3.2.2 Type d’une variable


Toute variable possède un type (ou classe). Intuitivement, le type d’une variable représente
l’ensemble des valeurs que peut prendre la variable.
Définition 3.2.3 — type d’une variable. Le type est la nature (la classe) de la valeur mémorisée
par une variable. Il est :
— défini à la création de la variable ;
— dynamique, c’est-à-dire qu’il peut évoluer lors de l’exécution du programme (contraire-
ment à d’autres langages comme par exemple Java, C++, Rust, etc où le type est statique
c’est-à-dire déclaré dans le code par le programmeur).

Nous verrons que Python définit un certain nombre de types :


— types simples (entiers, nombres à virgule flottante, complexes)
3.2 Variables & Affectation 21

— séquences (listes, n-uplets, intervalles, chaîne de caractères)


— collections : ensembles, dictionnaires.
Dans un premier temps, nous manipulerons des types simples. Nous y ajouterons le type chaîne
de caractère (str en Python). Une chaîne de caractères est une séquence ordonnée de caractères
(une sorte de vecteur de caractères). str est une classe 1 . Ces types sont décrits dans la table 3.1.

type (class) nom exemple de valeur remarques


int entier -2, 10 en base 10
-0b10, 0b1010 en binaire
-0x2, -0xA en hexadécimal
-0o2, 0o12 en octal
float virgule flottante 1.34, -0.6
complex complexe (3+4j)
str chaîne de caractères "spam" délimiteur : " ou ’
bool booléen True, False Deux valeurs uniquement

TABLE 3.1 – Types de base en Python

3.2.3 Attribuer une valeur : l’affectation


L’instruction permettant d’attribuer une valeur à une variable se nomme l’affectation. L’instruc-
tion d’affectation se note = en Python. La syntaxe de l’affectation est :

haffectationi : :=-
- hidentificateuri ‘=’ hexpressioni -

L’identificateur placé à gauche du signe = est le nom de la variable recevant la valeur de


l’expression située à droite. L’expression est évaluée en premier avant d’être affectée à la variable.
Cette expression peut être une constante ou une expression évaluable, comme une expression
logique, ou une expression arithmétique. . .
 Exemple 3.3 Voici quelques exemples d’affectation :

1 a = 5 # variable entière
2 b = 10 # variable entière
3 c = 7 # variable entière
4 reste = b % a # variable entière
5 quotient = b / a # variable entière
6 delta = b*b-4*a*c # variable entière
7 racine = (-b-math.sqrt(delta))/(2*a) # variable réelle
8 est_positif = delta > 0 # variable booléenne.

Quelques remarques sur cet exemple :


— nous n’avons pas encore étudié les différents opérateurs et fonctions mathématiques dispo-
nibles en Python. Cela n’empêche pas a priori de comprendre cet exemple. Les différents
opérateurs et fonctions mathématiques (et autres) seront abordés dans la section 3.3.
— lignes 1, 2, 3, 4 et 6 : déclaration et initialisation de cinq variables de type entier.
— lignes 5 et 7 : déclaration et initialisation d’une variable de type réel.
— ligne 8 : déclaration et initialisation d’une variable de type booléen.
— lignes 1 à 3 : affectation de valeurs constantes aux variables a, b et c.
1. cette notion sera définie plus loin
22 Chapitre 3. Instructions de base

— ligne 4 : l’opérateur % permet de calculer le reste de la division entière (ici le reste de la


division entière de b par a).
— ligne 5 : la division de b par a donne un résultat réel puisque l’opérateur utilisé est /. Nous
verrons plus loin comment forcer le résultat à être entier.
— ligne 6 : pour bien comprendre cette ligne, il faut connaître la priorité des opérateurs (nous y
reviendrons dans la section 3.3) : la multiplication et la division sont prioritaires sur l’addition
et la soustraction.
— ligne 7 : on peut faire deux remarques. En premier lieu, on peut noter ques les parenthèses
permettent de fixer la priorité voulue dans l’évaluation de l’expression. En second lieu,
math.sqrt est une fonction fournie par Python et permettant de calculer la racine carrée
d’une expression.
— ligne 8 : la variable est_positif sera affectée à la valeur vraie (true) si la variable delta
contient une valeur positive. Sinon elle sera affectée à la valeur faux (false).


Que se passe-t-il lors de la première affectation d’une variable ? Rappelons qu’en python, la
première affectation d’une variable correspond à sa déclaration. Prenons par exemple l’affectation
x=2. Lorsque Python exécute cette instruction (cf. figure 3.1 ), il :
1. crée une zone mémoire permettant de ranger l’objet de type entier 2 (class int),
2. cherche si x existe dans le contexte de nommage 2 . Ne le trouvant pas, une entrée x est ajoutée
à ce contexte,
3. finalise l’affectation en associant x à 2.

Contexte Mémoire

x 2

F IGURE 3.1 – Le contexte de nommage et la mémoire d’un programme Python

! Attention au sens de l’affectation !


Écrire 2=x n’a pas de sens !

Exemple 3.4 — autres exemples d’affectation. Référez vous à la figure 3.2 pour visualiser le
contexte et la mémoire.
— val = 3.14 crée la valeur flottante 3.14 (type float) en mémoire, déclare la variable val
dans le contexte, les associe.
— chaine = "Eggs" crée la chaîne de caractères "Eggs" (de type str), déclare la variable
chaine dans le contexte et les associe. 

Y Attention à bien distinguer le nombre 3.14 (type float) de la chaîne de caractères "3.14"
(type str). On peut faire des calculs sur la valeur 3.14 ; en revanche, on ne peut pas faire de
calculs sur la chaîne de caractères "3.14".

Y L’expression située à droite de l’instruction d’affectation peut faire intervenir la variable


située à gauche de l’instruction, par exemple :

2. La notion de contexte de nommage sera précisée ultérieurement. Pour l’instant, comprenez : l’ensemble des noms
manipulés par un programme.
3.2 Variables & Affectation 23

Contexte Mémoire

x 2
val 3.14
chaine "Eggs"

F IGURE 3.2 – Contexte de nommage et mémoire correspondant à l’exemple 3.4

i = i + 1

Dans cet exemple, on évalue d’abord l’expression de droite (i+1), puis on attribue la valeur
obtenue à la variable située à gauche (i). Ainsi, à la fin de cette affectation, la valeur de i
aura été augmentée de 1 : on dit que i a été incrémentée de 1.

Exercice 3.1 Quelles sont les valeurs et les types des différentes variables après l’exécution
des affectations suivantes ?

1 nom = "Dupont"
2 coef_a = 4.0
3 coef_b = 2
4 compteur1 = 0
5 compteur2 = 0.0
6 compteur1 = compteur1 + 2
7 compteur2 = 100
8 coef_c = coef_a + 50.0

3.2.4 Conversions de type


Les fonctions de la table 3.2 convertissent (si cela est possible) la valeur passée en paramètre
dans le type du même nom.

fonction traitement
int(valeur) troncature de la valeur à l’entier le plus proche de zéro
float(valeur) conversion de la valeur en flottant
str(valeur) conversion de la valeur numérique en chaîne

TABLE 3.2 – Les fonctions de conversion de type

 Exemple 3.5 — Conversion de type.


— a = int(3.0) ou a = int("3") sont équivalents à a = 3 avec a de type int.
— chaine = str(3.2) est équivalent à chaine = "3.2" avec chaine de type str. 

Y int parmet aussi des conversions dans une base donnée en utilisant son paramètre base.
Ainsi, int('FF', base=16) donne la valeur 255.
24 Chapitre 3. Instructions de base

3.3 Expressions
3.3.1 Définitions
Nous avons vu dans la section 3.2 que la partie droite d’une affectation pouvait être une
expression, nous n’avons pas défini précisément ce qu’est une expression. Nous allons examiner
de que peut être une expression, en partant des expressions les plus simples (les constantes), et en
enrichissant au fur et à mesure.
Définition 3.3.1 — Expression & opérateurs. Une expression est une série de calculs ayant
pour résultat une valeur d’un certain type.
Une expression utilise des opérateurs (+, -, *, .. . . ) agissant sur des opérandes qui peuvent
être des valeurs, des variables ou d’autres expressions.
Les expressions exploitent l’espace mémoire : la valeur d’une expression, si elle doit être
réutilisée dans la suite d’un programme, devra être stockée dans (affectée à) une variable.

 Exemple 3.6 — expressions.


— récupération de la valeur d’une variable précédemment affectée : x
— expression arithmétique : 4/3, (x+2) % 5 

3.3.2 Constantes
Il y a autant de types de constantes qu’il y a de types, aussi décrirons nous les constantes
entières (qui peuvent s’exprimer dans différentes bases), les constantes réelles et les constantes
chaînes de caractères.
Constantes entières
Les constantes entières peuvent s’exprimer en base 10, mais aussi en base 2, 8 ou 16. Il existe
donc quatre types de constantes entières :

hconstante_entièrei : :=-
-  hconstante_entière_décimalei  -
 hconstante_entière_octalei 
 hconstante_entière_hexadécimalei 

Les constantes entières décimales répondent à la règle suivante :

hconstante_entière_décimalei : :=-
-  ‘0’  -
 hchiffre_sauf_zéroi  
 
  hchiffrei 

 Exemple 3.7 Quelques exemples de constantes entières décimales :


— constantes entières décimales bien formées : 0, 134, 97856
— constantes entières démales mal formées : 0234 

Les constantes entières hexadécimales (base 16) répondent à la règle suivante :


 
hconstante_entière_hexadécimalei : :=-
- ‘0’  ‘x’   hchiffre_hexadécimali  -
 ‘X’ 

Un hchiffre_hexadécimali est un caractère de l’ensemble {0, . . . , 9, A, . . . , F, a, . . . , f}.


 Exemple 3.8 Exemples de constantes hexadécimales :
— constantes entières hexadécimales bien formées : 0x51a7, 0Xf45d, Ox0D8E
— constantes entières hexadécimales mal formées : 00x91, 0x91g 

Les constantes entières octales (base 8) répondent à la règle suivante :


3.3 Expressions 25

 
hconstante_entière_octalei : :=-
- ‘0’  ‘o’   hchiffre_octali  -
 ‘O’ 

Un hchiffre_octali est un caractère de l’ensemble {0, . . . , 7}.


 Exemple 3.9 — constantes entières octales bien formées : 0o542 0O234
— constantes entières octales mal formées : 0o999
0o999 n’est pas une constante entière octale bien formée, car 9 n’est pas un chiffre octal. 

Enfin, les constantes entières binaires doivent respecter la règle suivante :


 
hconstante_entière_binairei : :=-
- ‘0’  ‘b’    ‘0’  -
 ‘B’   ‘1’ 

 Exemple 3.10 — constantes binaires bien formées : 0b1001, 0B11010001


— constantes binaires mal formées : b0110, 00b0011, 111, 0b123 

Constantes réelles
Les constantes flottantes de type float doivent respecter les règles suivantes :

hconstante_réellei : :=-
- hchiffresi ‘.’    -
 hchiffresi   hexposanti 

hexposanti : :=-
-  ‘e’   hchiffresi -
 ‘E’   ‘+’ 
 ‘-’ 

 
hchiffresi : :=-
-  hchiffrei  -

 Exemple 3.11 — constantes flottantes bien formées : 0.22, 12., 3.665e12, 0.615e-4
— constantes flottantes mal formées : 23 (c’est une constante entière décimale) 

Constantes chaînes de caractères


Les constantes chaînes de caractères se présentent sous beaucoup de formes différentes en
Python. Nous ne rentrerons pas dans les détails pour l’instant et nous contenterons le la version la
plus simple de ces constantes chaînes :

hconstante_chaînei : :=-
-  hchaîne_courtei  -
 hchaîne_longuei 

 hcaractèrei 
hchaîne_courtei : :=-
-  ‘"’   ‘"’  -
 hcaractèrei 
 ‘’’   ‘’’ 

 hcaractèrei 
hchaine_longuei : :=-
- ‘"""’   ‘"""’  -
 hcaractèrei 
 ‘’’’’  ‘’’’’ 

Un hcaractèrei est n’importe quel caractère, sauf le délimiteur utilisé ou « \ ». Ce peut être
aussi une séquence d’échappement permettent de définir des caractères spéciaux. Les séquences
d’échappement sont résumées table 3.3.
Le différence entre une chaîne courte et une chaîne longue est la suivante :
26 Chapitre 3. Instructions de base

échappement description échappement description


\b effacement arrièrea \t tabulation
\n saut de ligneb \f saut de pagec
\r retour chariot \" guillemet double
\’ guillemet simple \\ backslash
\unnnn échappement unicoded
a b signifie backspace
b n signifie newline
c f signifie form feed
d où nnnn est un nombre hexadécimal : représente n’importe quel caractère

unicode par son code UTF16.

TABLE 3.3 – Séquences d’échappement de caractères en Java

— Dans une chaîne courte, vous ne pouvez pas passer à la ligne à l’intérieur de la chaîne
dans votre code source. Pour déclencher des passages à la ligne, il faut insérer un caractère
d’échappement \n.
— Dans une chaîne longue, vous pouvez passer à la ligne à l’intérieur de la chaîne. Ce passage
à la ligne fera partie de la chaîne de caractères.
 Exemple 3.12 — constantes chaîne de caractère. — "spam and eggs", ou 'spam and
eggs' représente :
spam and eggs
— "c'est une chaîne de caractères" ou 'c\'est une chaîne de caractères'
représente :
c'est une chaîne de caractères
— "spam\nand eggs" ou 'spam\nand eggs' ou

"""spam
and eggs
"""

ou

'''spam
and eggs
'''

représente la chaîne :
spam
and eggs


Constantes booléennes
Il n’y a que deux constantes booléennes :

hconstante_booléennei : :=-
-  ‘True’  -
 ‘False’ 
3.3 Expressions 27

Constante None
Cette constante particulière est utilisée pour signifier l’absence de valeur dans de nombreuses
situations. LA Constant None est du type None. Sa valeur de vérité est faux.

3.3.3 Expressions simples


Une expression simple répond à la règle suivante :

hexpression-simplei : :=-
-  hidentificateuri  -
 happel_de_fonctioni 
 ‘(’ hexpressioni ‘)’ 
 hconstantei 
 hacces-tableaui 

Le cas des constantes a déja été traité. Par hidentificateuri, on comprend identificateur de
variable. Les accès à un tableau seront traités dans le chapitre 7.

Exemples d’expressions simples


 Exemple 3.13 Voici quelques exemples d’affectations mettant en œuvre différentes formes
d’expressions simples.

b = 0x34 # constante hexadécimale (52 en base 10)


a = b # affectation de la valeur d'une variable à une autre variable
b = (3 * a) # expression parenthésée
s = "abcde" # constante chaîne de caractères
a = len(s) # appel de fonction
b = 0b01001000 # constante entière binaire (72 en base 10)
a = 0o721 # constante entière octale (465 en base 10)


appel de fonction
Un appel de fonction consiste à utiliser pour le besoin d’un calcul une fonction, soit prédéfinie
par le langage, soit définie dans un module externe (cf. section 3.6), soit écrite par nous même
ailleurs dans le programme (cf. chapitre 6).
Nous avons déjà rencontré des appels de fonction sans définir précisément leur syntaxe. Celle-ci
est la suivante :

happel_de_fonctioni : :=-
- hidentificateuri ‘(’   ‘)’ -
 ‘,’ 
  hexpressioni 

 Exemple 3.14 Python fournit une fonction prédéfinie len, qui renvoie la longueur d’une chaîne
de caractères (entre autres choses, nous reviendrons plus tard sur cette fonction qui a d’autres
usages).

a = 'spam and eggs'


b = len(a)

À la suite de l’exécution de ces deux instructions, b contient l’entier 13. 


28 Chapitre 3. Instructions de base

3.3.4 Expressions unaires


Une expression unaire est une expression mettant en œuvre des opérateurs unaires. Elle obéit à
la règle suivante :

hexpression_unairei : :=-
-  hexpression_simplei  -
  ‘+’  hexpression_unairei 
 ‘-’ 
 ‘~’ 

hidentificateuri est un identificateur de variable déclaré au préalable. Examinons maintenant


les différents opérateurs unaires.
— L’opérateur + indique une valeur positive 3 .
— L’opérateur - change le signe d’une expression.
— L’opérateur ~ inverse tous les bits de la valeur d’une expression.
 Exemple 3.15 Voici un exemple d’utilisation des différents opérateurs unaires :

a = 3
b = true

c = -a % c contient la valeur -3
d = ~a % d contient la valeur -4

Quelques explications supplémentaires sur le résultat de ~a ne seront pas de trop. a contient la


valeur 3. Cette valeur de type entier est représentable sur 8 bits. Voici la valeur binaire de a, suivie
de sa valeur hexadécimale pour plus de facilité de manipulation :

00000011
0 3

L’inversion de tous les bits de a produit donc la valeur binaire :

11111100
F C

Le type int représente les valeurs négatives en complément à deux : toutes les valeurs dont le
bit le plus significatif est à 1 sont des valeurs négatives représentées en complément à deux. Pour
retrouver la « vraie » valeur, il faut donc effectuer l’opération de complément à deux, c’est-à-dire
ajouter 1, puis inverser les bits :

ajout de 1 :
11111101
F D
inversion :
00000010
0 4

Donc l’inversion des bits de a produit la valeur 0xFFFFFFFC qui représente l’entier -4. 

3. Il est pratiquement inutile.


3.3 Expressions 29

3.3.5 Expressions multiplicatives


Les expressions multiplicatives sont celles utilisant les opérateurs de multiplication ou de
division. Elles doivent respecter la règle suivante :

hexpression_multiplicativei : :=-
- -
-  hexpression_unairei  -
 hexpression_multiplicativei  ‘*’  hexpression_unairei 
 ‘/’ 
 ‘//’ 
 ‘%’ 

opérandes numériques
Une règle importante lors de l’usage des opérateurs arithmétiques binaires est celle régissant
la conversion des types. En effet, il est important de savoir ce qui se passe lorsqu’une opération
arithmétique met en jeu des opérandes de types différents. Le type du résultat en fonction du type
des opérandes et de l’opérateur considéré est déterminé par la table 3.4.

opérateur opérande 1 opérande 2 résultat


*, /, // int int int
int float float
float int float
float float float
/ - - float

TABLE 3.4 – Type du résultat pour les opérations multiplicatives

La signification des opérateurs multiplicatifs est la suivante :


opérateur * Effectue une multiplication.
opérateur / Effectue une division. Notez que le résultat de cette opération est toujours une valeur
de tpye float.
opérateur // Effectue une division euclidienne (division entière).
opérateur % Calcule le reste de la division euclidienne de l’opérande de gauche par l’opérande de
droite.
 Exemple 3.16 — expressions multiplicatives.

10 * 3 # la valeur entière 30
10.0 * 3 # la valeur flottante 30.0
3 / 4 # la valeur flottante 0.75
10 // 3 # la valeur entière 3
10 // 3.0 # la valeur flottante 3.0
10 % 3 # la valeur entière 1
10.0 % 3 # la valeur flottante 1.0


chaînes de caractères
Lorsqu’une des deux opérandes est une chaîne de caractères (str) et l’autre un entier (int), la
chaine de caractère est répétée autant de fois que spécifié par la valeur entière.
 Exemple 3.17 — répétition de chaîne de caractères.
30 Chapitre 3. Instructions de base

'spam' * 3 # la chaîne de caractères 'spamspamspam'




3.3.6 Expressions additives


Les expressions additives sont celles utilisant les opérateurs d’addition et de soustraction. Elles
doivent respecter la règle suivante :

hexpression_additivei : :=-
- -
-  hexpression_multiplicativei  -
 hexpression_additivei  ‘+’  hexpression_multiplicativei 
 ‘-’ 

opérandes numériques
Le type du résultat est une valeur entière (int) si les deux opérandes sont entières. Si au moins
une des deux opérandes est de type float, le résultat est une valeur de type float.
L’opérateur + effectue une addition, et l’opérateur - une soustraction.
chaînes de caractères
L’opérateur + peut s’appliquer aux chaînes de caractère. Il réalise alors une concaténation, c’est
à dire qui « colle » les deux chaînes bout à bout en créant une nouvelle chaîne.
 Exemple 3.18 — concaténation.

a = "spam"
b = "and"
c = "eggs"

d = a + b + c # d contient la chaîne "spamandeggs"


e = a + ' ' + b + ' ' + c # "spam and eggs"


3.3.7 Expressions de décalage

! La présentation de ces opérateurs ne fera pas l’objet d’un cours, d’un TD ou d’un TP par
manque de ressource horaire. Toutefois, vous pouvez être amenés à utiliser ces expressions
agissant sur la représentation binaire des nombres dans d’autres contextes (autre module
d’enseignement ou projet).

Les expressions de décalage sont celles utilisant les opérateurs de décalage de bits. Elles doivent
respecter la règle suivante :

hexpression_de_décalagei : :=-
- -
-  hexpression_additivei  -
 hexpression_de_décalagei ‘<<’ hexpression_additivei 
 hexpression_de_décalagei ‘>>’ hexpression_additivei 

Les deux opérandes doivent obligatoirement être type entier.


La signification de ces opérateurs est la suivante :
n << s Le résultat est la valeur de n décalée à gauche de s bits.
n >> s Le résultat est la valeur de n décalée à droite de s bits avec extension du signe.
 Exemple 3.19 Voici quelques exemple d’utilisation des opérateurs de décalage :
3.3 Expressions 31

1 x = 5 << 2 # 20
2 x = 5 >> 2 # 1
3 x = 5 >> 3 # 0
4 x = -5 >> 2; # -2
5 x = -5 << 2; # -20

Quelques explications :
ligne 1 La représentation binaire de 5 sur 8 bits est :

00000101

Le décalage de cette représentation de deux positions vers la gauche donne :

00010100

La valeur est donc bien 20.


ligne 2 Le décalage de la représentation binaire de 5 de deux positions vers la droite donne :

00000001

La valeur est donc bien 1.


ligne 3 En décalant à droite la représentation binaire de 5 de 3 positions vers la droite, on voit
qu’on perd tous les bits à 1.
ligne 4 La représentation de -5 sur 8 bits utilise la méthode du complément à deux. Autrement dit
il faut, à partir de la représentation de 5, inverser les bits puis ajouter 1 :

11111011

On décale de deux positions vers la droite avec extension du signe, c’est à dire que les
positions de gauche libérées par le décalage sont remplies avec des 1 :

11111110

C’est un nombre négatif. Pour savoir lequel on calcule le complément à deux pour obtenir sa
valeur absolue :

00000010

La valeur absolue est 2, et donc le résultat est -2


ligne 5 Le décalage de la représentation binaire de -5 de 2 positions vers la gauche donne :

11101100

Le bit de signe est à un, le résultat est donc un nombre négatif. Pour savoir lequel, on calcule
son complément à deux pour trouver sa valeur absolue :

11101101
00010010

Il s’agit de 20. Donc le résultat de -5<<2 est bien -20. 

3.3.8 Expression booléennes


Le type booléen
32 Chapitre 3. Instructions de base

Définition 3.3.2 — type booléen. Une variable de type booléen (bool), peut prendre unique-
ment deux valeurs :
— True, correspondant à vrai ou à la valeur binaire 1 ;
— False, correspondant à faux ou à la valeur booléenne 0.

Y Toute valeur peut être transtypée en valeur booléenne à l’aide de la fonction bool(valeur) :
— toute valeur égale à 0 (ou None) est considérée comme False
— toute autre valeur est considérée comme True
Par défaut, bool() utilisée sans paramètres renvoie la valeur False.

Expressions booléennes
Opérateurs de comparaison
Les expressions booléennes mettent en œuvre des opérateurs de comparaison qui comparent
deux données du même type (numérique, chaîne. . . ), et produisent une valeur booléenne. Les
principaux opérateurs de comparaison son décrits dans la table 3.5.

Op. Signification Op. Signification


== égal (même valeur) != différent
> strictement supérieur < strictement inférieur
>= supérieur ou égal <= inférieur ou égal
b < x < B x est compris entre b et B
in appartenance à une liste not in non appartenance à une
d’éléments liste d’éléments
isinstance(x, t) x est du type t ? is égal (même objet en mémoire)

TABLE 3.5 – Les principaux opérateurs de comparaison en Python

Y
— la syntaxe b < x < B est propre à python. Il vaut mieux éviter de l’utiliser, ou alors
rester bien conscient que cette syntaxe n’existe généralement pas dans les autres
langages de programmation. Généralement on préfèrera écrire : x > b and x
< B. and est un opérateur booléen. Voir les opérateurs booléens ci-après.
— L’opérateur in sera abordé lorsque nous étudierons les listes au chapitre 7.

Concernant les opérateurs de comparaison usuels (==, !=, >= <=, > <), les deux opérandes
doivent être d’un type compatible. On peut comparer :
— Deux nombres : int ou float
— Deux chaînes de caractères (type str)
La comparaison de deux chaînes des caractères se fait selon l’ordre lexicographique (c’est à
dire, en simplifiant un peu, l’ordre du dictionnaire). Voir les exemples ci-dessous.
 Exemple 3.20 — comparaison de chaînes de caractères.
Expression Valeur Remarques
"avant" < "avarie" True car « avant » est sité avant « avarie » dans le dictionnaire
"avant" == "avant" True chaînes identiques
"Avant" == "avant" False voir les remarques ci-dessous


Dans un ordinateur, Les caractères sont représentés par une valeur numérique. La représentation
des caractères vous garantit que "A" < . . . < "Z" < . . . < "a" < . . . < "z". La table codant l’ordre
des caractères est la table UTF8. Cet ordre explique notamment que l’expression "Avant" <
"avant" est vraie.
3.3 Expressions 33

Par conséquent, si on souhaite comparer deux chaînes, le mieux est de les convertir au préalable,
soit entièrement en majuscules, soit entièrement en minuscules. Cela tombe bien, le type str
fournit une méthode (voir la section 3.6.3 pour une définition de ce qu’est une méthode) permettant
de transformer une chaine en son équivalent minuscule. C’est la méthode str.casefold(). Ainsi,
en utilisant cette méthode, l’expression "Avant".casefold() == "avant".casefold() vaut
True.
 Exemple 3.21 — expressions booléennes avec opérateurs de comparaison.
Condition Expression Python
la variable prog1 est-elle égale à 10 ? prog1 == 10
la variable prog2 est-elle comprise entre 10 et 20 ? 10 < prog2 < 20
la moyenne des notes prog1 et prog2 est-elle (prog1 + prog2)/2 > 10
supérieure à 10 ?
La note prog1 est-elle divisible par 3 ? prog1 % 3 == 0
x est-il différent de "a", "b" et "c" ? x not in ["a", "b", "c"]
x est-il du type int ? isinstance(x, int)


Y La valeur d’une expression booléenne peut bienentendu être affectée à une variable. Par
exemple, l’instruction reponse = (x == 5) affecte à la variable reponse le résultat de la
comparaison « x est-il égal à 5 ? ».

Opérateurs booléens
Les expressions booléennes peuvent également mettre en œuvre des opérateurs booléens qui
combinent des valeurs booléennes entre elles. Les principaux opérateurs booléens sont décrits dans
la table 3.6. Les valeurs de vérités des opérateurs logiques sont rappelés dans la table 3.7.

Op. Signification Op. Signification


or disjonction logique and conjonction logique
not négation logique

TABLE 3.6 – Opérateurs booléens

and True False or True False


not True False
True True False True True True
False True
False False False False True False

TABLE 3.7 – Tables de vérité de and, or et not

 Exemple 3.22 — conditions booléennes.


Condition Expression Python
La variable jour est-elle égale à "lundi" et (jour == "lundi") and (annee > 2000)
la variable annee est-elle supérieure à 2000 ?
Le jour est-il dans le week-end ? (jour == "samedi") or (jour == "dimanche")
ou jour in ["samedi", "dimanche"]
la variable x est-elle différente de 0 ? x != 0
ou (x < 0) or (x > 0)
La variable x est-elle comprise entre 0.5 (x >= 0.5) and (x < 1.5)

inclus et 1.5 ? ou 0.5 <= x < 1.5



34 Chapitre 3. Instructions de base

Y L’évaluation des expressions booléenne s’arrête dès que le résultat est sûr : par exemple, dans
l’expression x and y, si x est évalué à False, alors l’expression est False quelque soit la
valeur de y, qui n’est donc pas évalué. De même, pour x or y, si x est évalué à True, alors
l’expression est True, quelque soit la valeur de y, qui n’est pas évaluée.

3.3.9 Exercices sur les expressions


Exercice 3.2 — Séquence d’affectations et expressions entières. Quelles sont les valeurs
des variables a, b, q et r après la séquence d’affectations suivante ?

1 a = 19
2 b = 6
3 q = 0
4 r = a
5 r = r - b
6 q = q + 1
7 r = r - b
8 q = q + 1
9 r = r - b
10 q = q + 1


Exercice 3.3 — Séquences d’affectation et chaînes de caractères. Quelles sont les


valeurs des variables a et b après l’exécution de la séquence d’affectations suivante ?

1 a = "spam "
2 a = a*3
3 a = a + "and eggs "
4 b = "and spam "
5 a = a + b + "spam "*2


Exercice 3.4 — Séquences d’affectations et expressions booléennes. Quelles sont les


valeurs des variables c, d, e, f et g après l’exécution de la séquence d’affectations suivante ?

1 a = True
2 b = False
3 c = (a or b)
4 d = (a and b)
5 e = (a and c)
6 f = not (c or d)
7 g = not c and not d


Exercice 3.5 — Séquences d’affectations et expressions entières. Quelles sont les valeurs
des variables c, d, e, f et g après l’exécution de la séquence d’affectations suivante ?
3.4 Affectation composée 35

1 a = 0o37
2 b = Ox40
3 c = 0b11010
4 d = a + b
5 e = d + c
6 f = ~b
7 g = c >> 2


3.4 Affectation composée


Cette variante de l’affectation permet de réaliser simultanément une opération et l’affectation
de son résultat à une variable qui sert de premier opérande. Sa syntaxe est la suivante :

haffectation_composéei : :=-
- hidentificateuri  ‘+=’  -
 ‘-=’ 
 ‘*=’ 
 ‘/=’ 
 ‘%=’ 
 ‘//=’ 
 ‘**=’ 

une affectation composée du type variable op= expression est équivalente à l’affectation
variable = variable op expression.
 Exemple 3.23 — affectations composées. Les instructions suivantes :

1 a = 4
2 a += 1
3 a *= 2
4 a **= 2
5 a /= 2

Sont équivalentes aux instructions suivantes :

1 a = 4
2 a = a + 1
3 a = a * 2
4 a = a ** 2
5 a = a / 2

La trace de ces instructions est donnée dans la table 3.8. 

ligne a
1 4
2 5
3 10
4 100
5 50

TABLE 3.8 – Trace de l’exemple 3.23


36 Chapitre 3. Instructions de base

Exercice 3.6 — Affectation composée. Quelles sont les valeurs des variables après la
séquence d’affectations suivante ?

1 a = 'spam '
2 b = "and eggs "
3 a *= 3
4 a += b
5 a += "and " + "spam "*3


3.5 Entrées et sorties simples


Lors de la définition d’algorithmes, on se préoccupe très rarement de l’interaction avec un
utilisateur. Il en est tout autrement quand on passe à l’étape de programmation. Un programme
doit être à même de lire les données à traiter d’une façon ou d’une autre : via le clavier, à partir
d’un fichier, d’un port réseau ou de tout autre dispositif d’acquisition. De même, il doit être capable
d’écrire ses résultats : sur l’écran, sur une imprimante, dans un fichier. . .
Dans un premier temps, nous n’allons présenter que ce qui est nécessaire à l’acquisition de
données via le clavier, et restitutions de données à l’écran. Nous étudierons plus en détails les
entrées-sorties en Python au chapitre 9.

3.5.1 Sorties à l’écran


la fonction print
Les sorties à l’écran (à la console) se font à l’aide de la fonction prédéfinie print. Dans sa
forme la plus simple, cette fonction prend en paramètre une valeur de tout type (int,float,str,
etc.). Un retour chariot, c’est à dire un caractère de passage à la ligne, est ajouté par défaut après
chaque appel à print.
 Exemple 3.24 — affichage simple de données. Les instructions :

msg = "Bonjour"
valeur = 3.14
print(msg)
print(valeur)
print("fin")

print( "Bonjour" )
print( 3.14 )
print( "fin" )

produisent l’affichage
Bonjour
3.14
fin


Variantes de print
1. print(donnee1, donnee2, ...) affiche, sur une même ligne, et séparées par un espace,
toutes les données passées en paramètre.
3.5 Entrées et sorties simples 37

 Exemple 3.25 — affichage de données. Les instructions :

msg = "Bonjour"
valeur = 3.14
print(msg, valeur)
print("fin")

print("Bonjour", 3.14)
print("fin")

Produisent l’affichage suivant :


Bonjour 3.14
fin


2. print(donnee1, donnee2, ..., sep=chaine_sep, end=chaine_fin) affiche les don-


nées :
— en les séparant par la chaine_sep fournie par le paramètre optionnel sep (par défaut,
sep=" "),
— en terminant l’affichage par la chaine_fin fournie par le paramètre optionnel end (par
défaut end="\n".
 Exemple 3.26 — affichage de données. Le programme

1 msg = "Bonjour"
2 valeur = 3.14
3 print( msg, valeur, sep="--" )
4 print( "et" )
5 print( msg, valeur, end=">>" )
6 print( "fin" )

génère l’affichage suivant :


Bonjour--3.14
et
Bonjour 3.14>>fin

3.5.2 Entrées au clavier


Pour lire des données entrées au clavier par un utilisateur, Python fournit une fonction input.
Cette fonction accepte en paramètre optionnel une chaîne de caractères qui sera affichée avant
d’attendre la saisie de l’utilisateur.
La valeur saisie est renvoyée sous la forme d’une chaîne de caractères (str).
Plus précisément, l’instruction chaine = input('tapez une chaîne : ') :
1. affiche sur la console le message tapez␣une␣chaine␣:␣
2. capture les caractères saisis au clavier jusqu’à l’appui sur
3. les renvoie dans la variable chaine de type str
38 Chapitre 3. Instructions de base

 Exemple 3.27 — saisie de données. Les instructions :

chaine = input("Saisir une chaîne : ")


print(chaine, type(chaine))
chaine = input("Un entier : ")
print(chaine, type(chaine))
chaine = input("Une valeur flottante : ")
print(chaine, type(chaine))

donnent, pour les saisies de l’utilisateur indiquées en violet :


Saisir une chaine : toto
toto <class 'str'>
Un entier : 32
32 <class 'str'>
Une valeur flottante : -5.14
-5.14 <class 'str'>


Si vous souhaitez que la saisie de l’utilisateur soit d’un certain type, c’est à vous de réaliser un
transtypage en utilisant les fonctions de conversion de type vues dans la section 3.2.4.
 Exemple 3.28 — input avec transtypage. Les instructions :

chaine = input("Un entier : ")


nbre = int(chaine)
print(nbre, type(nbre))
chaine = input("Une valeur flottante : ")
val = float(chaine)
print(val, type(val))

donnent, pour les saisies de l’utilisateur indiquées en violet :


Un entier : 32
32 <class 'int'>
Une valeur flottante : -5.14
-5.14 <class 'float'>


3.6 Modules, fonctions et méthodes


3.6.1 Présentation
Python propose un ensemble de fonctions servant à différents calculs ou différentes tâches
utiles dans un programme. Certaines de ces fonctions sont fournées (rangées, déclarées) dans des
bibliothèques (appelées modules).
 Exemple 3.29 — Quelques modules (voir https://docs.python.org/3/library/index.html).
La table 3.9 liste quelques modules proposés par python (il y en a beaucoup d’autres). 

3.6.2 Caractéristiques et appel d’une fonction


3.6 Modules, fonctions et méthodes 39

module rôle examples de fonctions


– fonctions prédéfinies int, float, abs, input, print
math calculs mathématiques cos, sin, exp
random valeurs aléatoires rand, random
os, sys fonctions système chdir, getlogin, getpid
re expressions régulières match, compile
socket manipulation de sockets TCP socket, create_connection, gethostname

TABLE 3.9 – Quelques modules Python

Définition 3.6.1 — Caractéristiques d’une fonction. En plus d’un nom et d’un éventuel
module, les fonctions peuvent :
— dépendre de paramètres
— produire un résultat, appelé aussi valeur de retour (return value).

 Exemple 3.30 — extrait de la documentation de fonctions.

Définition 3.6.2 — Appel d’une fonction. Pour appeler une fonction, c’est-à-dire évaluer son
résultat pour des valeurs des paramètres données (appelés arguments), il faut :
— importer son module (si nécessaire) avec l’instruction import module (une seule fois
dans le programme)
— appeler la fonction avec la syntaxe :
— fonction si la fonction est déclarée dans le contexte courant ;
— module.fonction si la fonction appartient à un module importé.
suivi de parenthèses
— indiquer dans les parenthèses les arguments : chaque argument donne une valeur à chaque
paramètre de la fonction, dans le même ordre que celui de la déclaration des paramètres.
Cet appel se termine en renvoyant un résultat (une valeur), qui peut être affecté à une variable.

Le diagramme suivant résume cette syntaxe :

happel_de_fonctioni : :=-
-   hnom_fonctioni ‘(’ -
 hnom_modulei ‘.’ 
-   ‘)’ -
 ‘,’ 
  hargumenti 

 Exemple 3.31 — appel de fonction.


— La fonction sqrt(x) se trouve dans le module math. Pour importer ce module :

import math

on peut alors utiliser les fonctions de ce module :


40 Chapitre 3. Instructions de base

res = math.sqrt(3)
print(res)

La fonction sqrt(x) est alors évaluée, son paramètre x recevant l’argument 3. Le résultat
est stocké dans la variable res, qui est ensuite affichée sur la console :
1.7320508075688772
— La fonction max(a, b) est prédéfinie, elle n’appartient à aucun module. Les instructions :

res = max(1, 10)


print(res)

évaluent la fonction max(a, b) lorsque son paramètre a reçoit l’argument 1 et son paramètre
b reçoit l’argument b reçoit l’argument 10, stocke le résultat dans res, puis l’affiche sur la
console :
10
— La fonction getlogin() se trouve dans le module os, il faut donc importer le module :

import os

On peut alors appeler la fonction, qui ne prend pas de paramètres, ce qui n’empêche pas qu’il
faille indiquer les parenthèses :

log = os.getlogin()
print(log)

Ces instructions évaluent la fonction getlogin(), stockent le résultat dans log, puis l’af-
fichent sur la console :
wurbel.e


3.6.3 Méthodes
Certaines fonctions proposées dans les bibliothèques fournies par Python s’appliquent à des
objets d’un type particulier. Plus précisément, ils décrivent certains comportements ou certaines
propriétés des objets de cette classe (ce type).
Définition 3.6.3 — Méthode. Une méthode est une fonction décrivant un comportement d’un
objet d’une certaine classe.
Pour appeler une methode sur un objet, on utilise la syntaxe :

objet.methode(argument1, ..., argumentN)

 Exemple 3.32 — Exemples de méthodes de la bibliothèque Python.


— float.is_integer() renvoie True si la valeur flottante à laquelle elle s’applique représente
une valeur entière, False sinon. Par exemple, (-3.0).is_integer() renvoie True. De
même, la séquence d’instructions suivante :
3.7 Annexes 41

a = 2/3
b = 5.0
print(a.is_integer())
print(b.is_integer())

produira l’affichage suivant :


False
True
— complex.conjugate() renvoie le conjugué d’un nombre complexe. Par exemple, l’expres-
sion (3+2j).conjugate() renvoie le nombre complexe (3-2j). 

3.7 Annexes
3.7.1 Solutions des exercices

Solution de l’exercice 3.1 Pour répontre à la question, le plus simple est de réaliser une trace
du programme. La trace d’un programme décrit l’évolution de la valeur des variables au fur
et à mesure de l’exécution du programme. Ici, nous complèteronts cette trace en y ajoutant
l’information concernant le type de la valeur désignée par chaque variable.
ligne nom coef_a coef_b compteur1 compteur2 coef_c

valeur type valeur type valeur type valeur type valeur type valeur type

1 "Dupont" str — — — — — — — — — —
2 "Dupont" str 4.0 float — — — — — — — —
3 "Dupont" str 4.0 float 2 int — — — — — —
4 "Dupont" str 4.0 float 2 int 0 int — — — —
5 "Dupont" str 4.0 float 2 int 0 int 0.0 float — —
6 "Dupont" str 4.0 float 2 int 2 int 0.0 float — —
7 "Dupont" str 4.0 float 2 int 2 int 100 int — —
8 "Dupont" str 4.0 float 2 int 2 int 100 int 54.0 float

Quelques commentaires :
1. Après l’exécution de cette ligne, la variable nom désigne une valeur de type chaîne de
caractères (str).
2. Le fait d’utiliser une constante contenant le point décimal fait que la valeur désignée par
cette variable sera du type float.
3. Ici la constante numérique ne contient pas de point décimal, il s’agit donc d’une valeur de
type entier (int).
4. Là encore, la constante 0 ne contient pas de point décimal, il s’agit donc d’une valeur
entière (int).
5. La constante litérale 0.0 comprend un point décimal. Il s’agit donc d’une valeur à virgule
flottante (float), qui est différente du zéro de type entier à la ligne précédente.
6. On commence par effectuer l’expression située à droite du signe =. La valeur actuelle de
compteur1 est 0, donc la valeur de l’expression est 2 (de type int). On affecte ce résultat
à la variable compteur1 qui désigne donc maintenant la valeur 2.
7. On affecte à la variable compteur2 une nouvelle valeur. Celle-ci est de type entier (int)
puisque 100 ne contient pas de point décimal. La nouvelle valeur de compteur2 est donc
100, et le type de la variable est int. On a donc changé le type de cette variable.
8. Le résultat de l’expression à droite du signe d’affectation est 54.0. Il résulte de l’addition
de deux valeurs de type float : la valeur désignée par la variable coef_a (de type float)
et la valeur 50.0 (de type float elle aussi). Le résultat est dont logiquement de type
float.
42 Chapitre 3. Instructions de base

Solution de l’exercice 3.2 La trace du programme est :


ligne a b q r
1 19 — — —
2 19 6 — —
3 19 6 0 —
4 19 6 0 19
5 19 6 0 13
6 19 6 1 13
7 19 6 1 7
8 19 6 2 7
9 19 6 2 1
10 19 6 3 1

Solution de l’exercice 3.3 La trace du programme est :


ligne a b
1 spam␣ —
2 spam␣spam␣spam␣ —
3 spam␣spam␣spam␣and␣eggs␣ —
4 spam␣spam␣spam␣and␣eggs␣ and␣spam␣
5 spam␣spam␣spam␣and␣eggs␣and␣spam␣spam␣spam␣ and␣spam␣

Solution de l’exercice 3.4 La trace du programme est :


ligne a b c d e f g
1 True — — — — — —
2 True False — — — — —
3 True False True — — — —
4 True False True False — — —
5 True False True False True — —
6 True False True False False False —

7 True False True False False False False

Solution de l’exercice 3.5 La trace du programme est la suivante. Toutes les valeurs sont
données en base 10.
3.7 Annexes 43

ligne a b c d e f g
1 31 — — — — — —
2 31 64 — — — — —
3 31 64 26 — — — —
4 31 64 26 95 — — —
5 31 64 26 95 121 — —
6 31 64 26 95 121 -65 —
7 31 64 26 95 121 -65 6
Explications complémentaires sur la ligne 6 : La variable b contient la valeur décimale 64,
soit 0x40 en hexadécimal, ou encore 0b01000000 en binaire (la valeur est réprésentable sur un
octet). L’inversion de tous les bits de cette valeur donne donc 0b10111111. Il s’agit donc d’une
valeur négative (bit le plus significatif à 1) représentée en complément à deux. Pour trouver la
valeur absolue correspondante, on calcule le complément à deux (inversion de tous les bits suivit
d’un ajout de 1) :

1 0 1 1 1 1 1 1
--------------- inversion
0 1 0 0 0 0 0 0
+ 1
---------------
0 1 0 0 0 0 0 1

Donc la valeur absolue est 65, et la valeur de f = ~b est donc -65.


En ce qui concerne la ligne 7, la valeur binaire de c étant 0b11010, son décalage à droite de
deux positions binaires produit la valeur 0b110, soit la valeur décimale 6.
4. Structures alternatives

4.1 Alternative simple : si. . . alors. . . sinon. . .


Jusqu’à présent, les instructions que nous avons rencontrées (affectation, instructions d’entrée-
sortie simples) s’exécutent séquentiellement (les unes à la suite des autres), dans l’ordre où elles
ont été écrites. Le « chemin » suivi pour exécuter un algorithme est appelé le flux d’instructions
(figure 4.1). Les constructions qui modifient ce flux sont appelées instructions de contrôle du flux.
Les instructions sont donc exécutées dans l’ordre où elles apparaissent, sauf quand on rencontre
une instruction de contrôle de flux : ces instructions vont permettre de suivre un autre chemin,
suivant les circonstances. En particulier, c’est le cas de l’instruction conditionnelle, qui n’exécute
une instruction que sous certaines conditions.

instruction1 instruction2 instruction3

F IGURE 4.1 – Flux d’instructions

La syntaxe générale d’une alternative simple est présentée dans la figure 4.2. Le fonctionnement
de cette construction est rappelé dans la figure 4.3.

if condition_booleenne:
# instructions si la condition est vraie
instruction
instruction
else:
# instructions si la condition est fausse
instruction
instruction
# fin du si/sinon
suite_du_programme

F IGURE 4.2 – Syntaxe du si. . . alors. . . sinon en Python


46 Chapitre 4. Structures alternatives

if condition_booleenne:
# instructions si la condition est vraie
instruction
uniquement si condition est True
instruction
else:
# instructions si la condition est fausse
instruction
uniquement si condition est False
instruction
# fin du si/sinon
suite_du_programme suite du déroulement séquentiel

F IGURE 4.3 – Fonctionnement de la structure si. . . alors. . . sinon

Le fonctionnement de cette instruction est le suivant :


1. La condition condition_booleenne est évaluée.
(a) Si elle vaut True, alors le bloc d’instructions qui suit le if est exécuté (mais pas le
bloc qui suit le else) ;
(b) Sinon (Si la condition vaut False), le bloc d’instructions qui suit le else est exécuté
(mais pas le bloc qui suit le if)
2. Une fois les instructions de la structure if/else exécutées le programme continue son
exécution avec la première instruction suivante.

! En python, c’est l’indentation qui délimite les blocs d’instructions. Une mauvaise indentation
conduira imanquablement à une mauvaise exécution.

On crée le niveau d’intentation suivant en appuyant sur la touche de tabulation . Si on


regarde une structure alternative simple du point de vue de l’indentation, voici ce qu’on obtient :

if condition_booleenne:
# instructions si la condition est vraie
instruction
instruction
else:
# instructions si la condition est fausse
instruction
instruction
# fin du si/sinon
suite_du_programme

 Exemple 4.1 — alternative. Les instructions :

chaine_entier = input("Saisissez un entier : ")


entier = int(chaine_entier)
if entier > 4:
# instructions si la condition est vraie
print("oui :", entier, "est supérieur à 4")
4.2 Condition simple : si. . . 47

else:
# instructions si la condition est fausse
print("non :", entier, "est inférieur ou égal à 4")
# fin du si/sinon et suite du programme
print("fin")

donnent à l’exécution :
Cas 1 :
Saisissez un entier : 32
oui : 32 est supérieur à 4
fin

Cas 2 :
Saisissez un entier : 3
non : 3 est inférieur ou égal à 4
fin

Exercice 4.1 — Maximum. Écrire un programme python qui détermine le maximum de deux
nombres. 

 Exemple 4.2 — Fonction « porte ». On considère la fonction « porte » f dont le graphe est

donné ci-dessous. Le programme suivant permet de calculer y = f (x).

chaine_x = input("x=") y
x = float(chaine_x)
2
if (x < -1) or (x > 2):
y = 0
else: x
-1 0 2
y = 2


Exercice 4.2 — fonction « porte ». Proposer une autre alternative simple pour calculer la
fonction « porte » de l’exemple 4.2. 

4.2 Condition simple : si. . .


La condition simple correspond au cas où il n’y a pas d’alternative sinon. En Python, cela se
traduira par une absence de else. La syntaxe de la condition simple en Python est présentée dans
la figure 4.4. Son fonctionnement est rappelé dans la figure 4.5.
Cette structure teste la condition_booleenne en évaluant si elle st True ou False. Si elle
est True, alors le bloc d’instructions qui suit le if est exécuté. Sinon (si la condition est False),
le bloc d’instructions qui suit le if n’est pas exécuté. Dans les deux cas, l’exécution se poursuit
avec la première instruction de la suite_du_programme.
 Exemple 4.3 — condition simple. Les instructions
48 Chapitre 4. Structures alternatives

if condition_booleenne:
# instructions si la condition est vraie
instruction
instruction
# fin de la condition
suite_du_programme

F IGURE 4.4 – syntaxe du si. . . alors. . . en Python

if condition_booleenne:
# instructions si la condition est vraie
omis si
instruction la condition
uniquement si condition est True
instruction est False
# fin de la condition
suite_du_programme suite du déroulement séquentiel

F IGURE 4.5 – Fonctionnement de la structure conditionnelle simple si. . . alors. . .

chaine_nb = input("Saisissez un nombre")


nb = float(chaine_nb)
if nb < 0:
# instructions si la condition est vraie
var = -var
# fin de la condition, suite du programme
print("Sa valeur absolue est",var)
print("fin")

donnent à l’exécution :
Cas 1 :
Saisissez un nombre : 5
Sa valeur absolue est 5
fin
Cas 2 :
Saisissez un nombre : -2
Sa valeur absolue est 2
fin


4.3 Alternatives multiples : si. . . sinon si. . . sinon. . .


L’alternative multiple correspond au cas où le sinon s’enchaine sur un autre si. En Python,
cela se traduira par l’utilisation du mot clé elif (abbréviation de else if, autrement dit sinon si. La
4.3 Alternatives multiples : si. . . sinon si. . . sinon. . . 49

syntaxe de l’alternative multiple en Python est présentée dans la figure 4.6. Son fonctionnement est
rappelé dans la figure 4.7.

if condition_booleenne_1:
instruction
instruction
elif condition_booleenne_2:
instruction
instruction
else:
instruction
instruction
suite_du_programme

F IGURE 4.6 – Traduction de l’alternative multiple en Python

if condition_booleenne_1:
instruction s’exécute si lacondition 1 est True

instruction
elif condition_booleenne_2: s’exécute si la condition 2 est False
instruction et la condition 2 est True
instruction
else: s’exécute si les conditions 1 & 2
instruction sont False
instruction
suite_du_programme suite du déroulement séquentiel

F IGURE 4.7 – Fonctionnement de l’alternative multiple

Y Quelques remarques sur les structures alternatives multiples en Python :


— Le bloc elif peut apparaitre autant de fois qu’on a de conditions alternatives à tester.
— Dès qu’une des conditions booléennes est True, alors les conditions testées dans
les elif qui suivent ne sont plus évaluées et l’exécution se poursuit à la suite du
programme.
— Le bloc else est optionnel.

 Exemple 4.4 — alternatives multiples. Les instructions :

chaine_nb = input("Saisissez un nombre : ")


nb = float(chaine_nb)
if nb < 4:
print(nb, "est négatif")
elif nb > 0:
print(nb, "est positif")
else:
print(nb, "est nul")
print("fin")
50 Chapitre 4. Structures alternatives

donnent à l’exécution :
Cas 1 :
Saisissez un nombre : 5
5 est positif
fin
Cas 2 :
Saisissez un nombre : -2
-2 est négatif
fin
Cas 3 :
Saisissez un nombre : 0
0 est nul
fin


Exercice 4.3 — Température de l’eau. À pression ambiante, l’eau est sous forme de glace si
la température est inférieure à 0°C, sous forme de liquide si la température est comprise entre
0°C et 100°C et sous forme de vapeur au-delà de 100°C.
Écrivez un programme Python utilisant une alternative multiple qui demande à l’utilisateur
de saisir une température, et affiche l’état de l’eau correspondant. 

Exercice 4.4 Écrivez un programme Python utilisant une alternative multiple qui détermine la
catégorie sportive d’un enfant en fonction de son âge :
— Poussin de 6 à 7 ans,
— Pupille de 8 à 9 ans,
— Minime de 10 à 11 ans,
— Cadet de 12 à 14 ans.


4.4 Structures alternatives : bilan


Le diagramme suivant résume la syntaxe des structures alternatives :

hstructure_alternativei : :=-
- ‘if’ hexpression_booléennei ‘:’ hbloci -
-   -
  ‘else’ ’ :’ hbloci 
 
  ‘elif’ hcondition_booléennei ‘:’ hbloci 
 

Pour finir, voici un exemple faisant le bilan sur les structures alternatives.
 Exemple 4.5 Une UE contient deux modules M1 et M2.
— L’UE est validée si les notes aux deux modules sont supérieures à 10.
— il y a rattrapage si un seul des modules a une note supérieure à 10.
— si les deux notes sont inférieures à 10, l’UE n’est pas validée.
Les variables m1 et m2 représentent les notes obtenues à chaque module.
Les trois solutions suivantes sont équivalentes.
4.5 Annexes 51

1. avec deux structures si sinon imbriquées

if m1 >= 10 and m2 >= 10:


print("validé")
else:
if m1 >= 10 or m2 >= 10:
print("rattrapage")
else:
print("refusé")

2. avec une alternative multiple :

if m1 >= 10 and m2 >= 10:


print("validé")
elif m1 >= 10 or m2 >= 10:
print("rattrapage")
else:
print("refusé")

3. avec des conditions simples :

if m1 >= 10:
if m2 >= 10:
print("validé")
else:
print("rattrapage")
else:
if m2 >= 10:
print("rattrapage")
else:
print("refusé")


4.5 Annexes
4.5.1 Solutions des exercices

Solution de l’exercice 4.1 Voici une solution possible :

v_chaine1 = input("Entrez un nombre :")


v1 = int(v_chaine1)
v_chaine2 = input("Entrez un nombre :")
v2 = int(v_chaine2)
max = 0
if v1 > v2:
max = v1
else:
max = v2
print("le maximum est :", max)
52 Chapitre 4. Structures alternatives

Solution de l’exercice 4.2 Voici une autre façon d’écrire la fonction porte de l’exemple 4.2
avec une alternative simple :

x = float(chaine_x)
if (x >= -1) and (x <= 2):
y = 2
else:
y = 0

Solution de l’exercice 4.3 Voici un programme Python utilisant une alternative multiple qui
demande à l’utilisateur de saisir une température, et affiche l’état correspondant.

chaine_temp = input("Saisissez une température :")


temp = float(chaine_temp)
etat = ""
if temp > 100:
etat = "vapeur"
elif temp >= 0:
etat = "liquide"
else:
etat = "glace"
print("État de l'eau :", etat)

Solution de l’exercice 4.4 Voici un programme possible déterminant la catégorie sportive


d’un enfant.

chaine_age = input("Saisissez l'âge de l'enfant")


age = int(chaine_age)
cat = ""
if age < 6:
cat = "Catégorie inconnue"
elif age <= 7:
cat = "Poussin"
elif age <= 9:
cat = "Pupille"
elif age <= 11:
cat = "Minime"
elif age <= 14:
cat = "Cadet"
else:
cat = "Catégorie inconnue"
print "Catégorie :", cat)
5. Structures répétitives

5.1 Principes généraux


Définition 5.1.1 — Structure répétitive. Une structure répétitive (ou boucle) est un bloc
d’instructions exécuté un certain nombre de fois (de 0 à une infinité).

Python possède deux structures répétitives :


boucle while les boucles while (tant que) répètent un bloc d’instruction tant qu’une condition
n’est pas vérifiée ; la condition est une expression booléenne (comme dans les structures
alternatives).
bouche for Dans un certain nombre de cas, le nombre de répétitions est connu du programmeur
(parcours des éléments d’une liste, répétition d’une même action. . . ) ; dans ce cas, on préfère
utiliser la boucle for à la syntaxe plus simple.

5.2 Itération conditionnelle : la boucle while


Définition 5.2.1 — Boucle while. La boucle while répète un bloc d’instructions tant qu’une
condition booléenne n’est pas vérifiée. Sa syntaxe est :
initialisation_condition
while condition:
instruction
...
modification_condition
suite_du_programme
Trois étapes la constituent :
1. Initialisation de la condition.
2. Test de la condition à chaque itération de la boucle.
3. Modification de la condition à chaque itération.

Y Quelques remarques sur le while :


54 Chapitre 5. Structures répétitives

— Une itération est une exécution du bloc d’instructions.


— Dès que la condition n’est plus vraie, le programme se poursuit avec les instructions
qui suivent le bloc répété.
— Pour ne pas que la boucle se répète sans fin, le bloc d’instructions répété doit obliga-
toirement faire des modifications qui soient susceptibles de changer la valeur de la
condition booléenne.

Ces boucles sont utiles lorsque le nombre d’itérations n’est pas connu à l’avance, par exemple
lorsque ce nombre dépend d’une action de l’utilisateur, ou du résultat d’une calcul réalisé dans la
boucle.
 Exemple 5.1 — vérification d’une saisie clavier. Les fragments de programme suivants
imposent à l’utilisateur de saisir au clavier soit la lettre 'O', soit la lettre 'N'.
Pour construire la condition de la boucle, on utilise la variable rep qui contient la saisie de
l’utilisateur, et que l’on compare aux valeurs attendues.
Les deux variantes du programme se distinguent par leur étape d’initialisation de la condition :
1. rep = input("Tapez O/N : "). Dans ce cas, une saisie est réalisée avant le test. Il est
donc possible qu’on ne « rentre » jamais dans la boucle (si l’utilisateur a saisi soit 'O', soit
'N').
2. rep = "" qui affecte une valeur garantissant l’entrée dans la boucle.
Variante 1

rep = input("Tapez O/N : ") # initialisation


while not (rep == 'O' or rep == 'N'): # condition de boucle
rep = input("O/N svp; recommencez : ") # modif. de la variable
print("fin")

Variante 2

rep = "" # initialisation


while not (rep == 'O' or rep == 'N'): # condition de boucle
rep = input("Tapez O/N : ") # modif. de la variable
print("fin")

Ces deux variantes donnent à l’exécution, pour les mêmes saisies utilisateur :
Variante 1 (2 passages dans la Variante 2 (3 passages dans la
boucle). boucle).
Tapez O/N : i Tapez O/N : i
O/N svp; recommencez : p Tapez O/N : p
O/N svp; recommencez : O Tapez O/N : O
fin fin


 Exemple 5.2 — pgcd. Le plus grand commun diviseur de deux entiers a et b peut se calculer en
appliquant la relation de récurrence pgcd(a, b) = pgcd(b, a%b) si b 6= 0, jusqu’à ce que le reste de
(a%b) soit nul (pgcd(d, 0) = d si d 6= 0).
Par exemple, pour calculer le pgcd de a = 12 et b = 18, on applique trois fois cette relation de
récurrence : pgcd(12, 18) = pgcd(18, 12) = pgcd(12, 6) = pgcd(6, 0) = 6
Une façon de considérer la relation pgcd(a, b) = pgcd(b, a%b) est de remarquer qu’elle nous
demande de remplacer a par b et b par a%b tant que le reste n’est pas nul, auquel cas pgcd(a, 0) = a.
Cela conduit à l’algorithme suivant, et a sa traduction en Python (notez que dans la version
python,nous donnons les valeurs de a et b. Pour l’instant on ne sait pas définir en Python de
traitement réutilisable, de fonction) :
5.3 La boucle for 55

algorithme P GCD
entrées :
a : entier
b : entier
sorties :
1 a = 12
pgcd : entier
2 b = 18
variables :
3 while b != 0:
r : entier
4 r = a % b
début
5 a = b
tant que b 6= 0 faire
6 b = r
r ← a%b
7 pgcd = a
a←b
b←r
fin tant que
pgcd ← a
fin algorithme
La trace de l’exécution de ce programme est donnée dans la table . 

ligne a b r pgcd commentaires


1 12 — — —
2 12 18 — —
3 12 18 — — condition vérifiée, on rentre dans la boucle
4 12 18 12 —
5 18 18 12 —
6 18 12 12 — modif. de la condition
3 18 12 12 — condition vérifiée, on rentre dans la boucle
4 18 12 6 —
5 12 12 6 —
6 12 6 6 — modif. de la condition
3 12 6 6 — condition vérifiée, on rentre dans la boucle
4 12 6 0 —
5 6 6 0 —
6 6 0 0 — modif. de la condition
3 6 0 0 — condition non vérifiée ! on sort
7 6 0 0 6 résultat final

TABLE 5.1 – Trace du calcul du pgcd de 12 et 18

5.3 La boucle for


5.3.1 Le compteur d’itérations
Définition 5.3.1 — Boucle for. Pour répéter un bloc d’instructions n fois, une boucle for utilise
un compteur d’itération. La forme la plus simple de la boucle for est la suivante :
56 Chapitre 5. Structures répétitives

for compteur in range(n):


instruction # Début du bloc à répéter
...
instruction
# Fin du for
suite_du_programme

— Le compteur s’initialise à 0 ; après chaque itération, il augmente de 1.


— Lorsqu’il atteint n, le bloc d’instructions a été exécuté n fois, il n’est donc plus exécuté et
le programme poursuit son exécution avec les instructions qui suivent le bloc.

Y Les compteurs sont souvent nommés i, j ou k. . .

5.3.2 Répétition
 Exemple 5.3 — boucle itérant le même affichage trois fois. Les instructions suivantes :

1 for i in range(3):
2 print("*", end=" ")
3 print("fin")

itèrent trois fois et produisent l’affichage suivant :


* * * fin
La trace d’exécution du code est donnée table 5.2. 

ligne i affichage commentaire


1 0 initialisation du compteur à 0
2 0 *␣ fin de la 1reitération de boucle
1 1 *␣
2 1 *␣*␣ fin de la 2eirération de boucle
1 2 *␣*␣
2 2 *␣*␣*␣ fin de la 3eitération de boucle
1 2 *␣*␣*␣ Le compteur atteint le nombre d’itér. voulu
3 2 *␣*␣*␣fin

TABLE 5.2 – Tracé de la boucle for affichant * * * fin.

Y Ce code est équivalent à print("* "*3 + "fin").

5.3.3 Répétition utilisant le compteur de boucle

Y Le compteur de boucle est une variable comme une autre. Il peut être utilisé dans les
instructions de la boucle pour faire varier leeurs résultats d’une itération à une autre.

 Exemple 5.4 — affichage des nombres de 2 jusqu’à 6 (exclu). Les instructions suivantes :

1 for i in range(4):
2 print(i+2, end=" ")
3 print("fin")
5.3 La boucle for 57

affichent les nombres de 2 à 5 :


2 3 4 5 fin
La trace de cette exécution est donnée dans la table 5.3. 

ligne i affichage commentaire


1 0 initialisation du compteur à 0
2 0 2␣ fin de la 1reitération de boucle
1 1 2␣
2 1 2␣3␣ fin de la 2eirération de boucle
1 2 2␣3␣
2 2 2␣3␣4␣ fin de la 3eitération de boucle
1 3 2␣3␣4␣
2 3 2␣3␣4␣5␣ fin de la 4eitération de boucle
1 3 2␣3␣4␣5␣ Le compteur a atteint le nombre d’itér. voulu
3 3 2␣3␣4␣5␣fin

TABLE 5.3 – Tracé de la boucle for affichant 2 3 4 5 fin.

! Le compteur de boucle ne doit pas être modifié dans les instructions de la boucle !. Quoi
qu’il en soit, l’ensemble des valeurs que doit prendre le compteur de boucle est précalculé
au premier passage dans la boucle. Quelles que soient les modifications faites au compteur,
chaque nouvelle itération donne au compteur la prochaine valeur attendue.
Ce comportement est spécifique à Python. Tous les langages de programmation ne se com-
portent pas comme ça.

 Exemple 5.5 — modification du compteur de boucle. Les instructions :

1 for i in range(2):
2 print(i, end=" ")
3 i = 0
4 print("fin")

produisent l’affichage suivant :


0 1 fin
La trace de cette exécution est donnée dans la table 5.4. 

ligne i affichage commentaire


1 0 initialisation du compteur à 0
2 0 0␣
3 0 0␣ fin de la 1reitération de boucle
1 1 0␣
2 1 0␣1␣
2 0 0␣1␣ fin de la 2eitération de boucle
1 0 0␣1␣ Le compteur a atteint le nombre d’itér. voulu
4 0 0␣1␣fin

TABLE 5.4 – Tracé de la boucle for affichant 0 1 fin.


58 Chapitre 5. Structures répétitives

5.3.4 Valeur initiale du compteur


Définition 5.3.2 — Boucle for avec valeur initiale non nulle. La syntaxe de la boucle for
répétant un bloc d’instructions en utilisant un compteur allant d’une valeur initiale (inclue) à
une valeur finale (exclue) est :

for compteur in range(val_ini, val_fin_exclue):


instructions

Le nombre d’itérations est alors val_fin_exclue - val_ini ; la boucle s’arrête lorsque le


compteur atteint la valeur val_fin_exclue-1.

 Exemple 5.6 — affichage des nombres de 2 à 5 (exclu). Les instructions suivantes affichent
les nombres de 2 à 4 :

1 for i in range(2,5):
2 print(i, end=" ")
3 print(fin)

L’affichage produit est :


2 3 4 fin
La trace de cette exécution est donnée dans la table 5.5. 

ligne i affichage commentaire


1 2 initialisation du compteur à 2
2 2 2␣ fin de la 1reitération de boucle
1 3 2␣
2 3 2␣3␣ fin de la 2eitération de boucle
1 4 2␣3␣
2 4 2␣3␣4␣ fin de la 3eitération de boucle
1 4 2␣3␣4␣ Le compteur a atteint sa valeur finale
3 4 2␣3␣4␣fin

TABLE 5.5 – Tracé de la boucle for affichant 2 3 4 fin.

5.3.5 Incrément du compteur


Définition 5.3.3 — Boucle for avec incrément du compteur différent de 1. La syntaxe
suivante :

for compteur in range(val_ini, val_fin_exclue, increment):


instructions

initialise le compteur à la valeur val_ini, puis, à chaque itération, ajoute au compteur la valeur
de increment jusqu’à ce qu’il égale ou dépasse val_fin_exclue.

 Exemple 5.7 — affichage des nombres pairs de 2 à 8 (exclu). Les instructions suivantes :

1 for i in range(2, 8, 2):


2 print(i, end=" ")
3 print("fin")
5.4 Équivalence entre boucle for et boucle while 59

produit l’affichage suivant :


2 4 6 fin
La trace d’éxécution de ces instructions est donnée dans la table 5.6. 

ligne i affichage commentaire


1 2 initialisation du compteur à 2
2 2 2␣ fin de la 1reitération de boucle
1 4 2␣
2 4 2␣4␣ fin de la 2eitération de boucle
1 6 2␣4␣
2 6 2␣4␣6␣ fin de la 3eitération de boucle
1 6 2␣4␣6␣ Le compteur a atteint sa valeur finale
3 6 2␣4␣6␣fin

TABLE 5.6 – Tracé de la boucle for affichant 2 4 6 fin.

Exercice 5.1 — Dessin d’étoiles. Écrivez un programme qui affiche les n lignes suivantes
(l’exemple est donné pour n = 6) :
******
*****
****
***
**
*
On rappelle qu’en Python, l’expression 5*'r' a pour résultat 'rrrrr' et que l’expression
2*'to' a pour résultat 'toto'. 

5.4 Équivalence entre boucle for et boucle while


Lorsque le nombre d’itérations est connu avant l’exécution de la boucle et qu’on peut le
dénombrer avec un compteur d’itération allant d’une valeur initiale ini jusqu’à une valeur finale
fin, en s’incrémentant à chaque itération d’une valeur inc, on peut employer indifféremment une
bouche for ou une boucle while.

for compteur in range(ini, fin, inc): compteur = init


instruction while compteur < fin:
... instruction
suite_du_programme ...
compteur += inc
suite_du_programme

 Exemple 5.8 — affichage des nombres impairs de 1 à 20. Avec une boucle for :

for i in range(1, 20, 2):


print(i, end=" ")
60 Chapitre 5. Structures répétitives

print("fin")

Avec une boucle while :

i = 1
while i < 20:
print(i, end=" ")
i += 2
print("fin")

Les deux programmes produisent l’affichage suivant :


1 3 5 7 9 11 13 15 17 19 fin


Exercice 5.2 — Dessin d’étoiles. Réécrivez l’exercice 5.1 en utilisant une boucle while. 

5.5 Boucles et structures alternatives


Étant donné que le bloc d’instructions d’une boucle peut contenir n’importe quelle instruction,
il peut, en particulier, contenir une structure alternative. C’est l’indentation qui permet d’identifier
les blocs d’instructions : dans l’exemple suivant, les instruction du if sont identées une fois par
rapport au if, qui lui même est indenté une fois par rapport au for.
 Exemple 5.9 — affichage des nombres impairs de 0 à 20. Les instructions suivantes :

for i in range(20):
if (i % 2) != 0:
print(i, end=" ")
else:
print("-", end=" ")
print("fin")

produisent l’affichage suivant :


- 1 - 3 - 5 - 7 - 9 - 11 - 13 - 15 - 17 - 19 fin


5.6 Boucles avec variables d’accumulation


5.6.1 Principe
— Les boucles s’utilisent couramment avec une variable d’accumulation dont la valeur s’actualise
à chaque itération.
— L’actualisation peut prendre des formes diverses : ajout d’une valeur à la variable (nombre
ou chaîne de caractères), multiplication par une valeur. . .
— Le choix du type de boucle (for ou while), dépend de l’application visée, et se fait toujours
sur le critère de la connaissance du nombre d’itérations à l’avance ou pas.
5.6 Boucles avec variables d’accumulation 61

5.6.2 Accumulation additive


 Exemple 5.10 — solde d’un compte bancaire. Afficher le solde d’un compte bancaire
initialement égal à 0, sur lequel est versé un montant fixe de 50 euros tous les mois, après quatre
ans de fonctionnement :
— variable d’accumulation : le solde
— utilisation d’une boucle for car le nombre de mois (ici 4*12) est connu.

solde = 0 # initialisation
for mois in range(1, 4 * 12):
solde = solde + 50
print("solde final :", solde)
print("fin")

L’affichage produit par ce programme est :


solde final : 2350


Y On perd les valeurs intermédiaires du solde. Nous verrons comment conserver ces valeurs si
nécessaire lors de l’étude des listes (chapitre 7).

 Exemple 5.11 — Quand pourrais-avoir un iPhone ?. Partant d’un livret contenant 50 euros,
sur lequel est viré 200 euros chaque année, avec 0.75% d’intérêt, combien d’années faut-t-il à son
titulaire pour acheter un iPhone ?
— Variable d’accumulation : le solde avec ajout des intérêts et du versement à chaque itération.
— La boucle sera une boucle while avec un compteur d’années (on ne sait pas a priori combien
d’années seront nécessaires).

solde = 50
annee = 0
while solde < 700:
solde = solde * (1 + 0.75/100) + 200
annee = annee + 1
print("nombre d'années :", annees)
print("Solde :", solde)

L’affichage produit est le suivant :


Nombre d'années : 4
Solde : 860.5620439082031
Le nombre d’années correspond au nombre d’itérations de la boucle. 

 Exemple 5.12 — somme des entiers de 1 à 36. Le programme suivant calcule la somme des
entiers de 1 à 36 inclus :

somme = 0 # initialisation
for i in range(1, 36 + 1):
somme = somme + i
print("somme finale :", somme)

L’affichage est :
62 Chapitre 5. Structures répétitives

somme finale : 666




Y Un programme utilisant une variable d’accumulation doit toujours :


1. initialiser la variable d’accumulation
2. programmer la structure répétitive de façon à actualier la valeur de la variable d’accu-
mulation.
La valeur finale de la variable est obtenue en sortie de boucle.

5.6.3 Accumulation multiplicative


 Exemple 5.13 — calcul itératif d’une puissance. Le programme suivant calcule xn . Le résultat
est rangé dans la variable res. La table 5.7 donne une trace du programme pour x=2 et n=4. Le
calcul se base sur le fait que

xn = x| × .{z
. . × }x,
n fois

soit, dans l’exemple tracé dans la table 5.7 : 24 = 2 × 2 × 2 × 2

1 str_x = input("x = ")


2 str_n = input("n = ")
3 x = int(str_x)
4 n = int(str_n)
5 res = 1
6 i = 1
7 while i <= n:
8 res = res * x
9 i += 1
10 print(str_x + "^" + str_n, "=", res)

ligne i i <= 4 res calcul commentaire


5–6 1 1
7 1 True 1 1re itération
8–9 2 True 2 1 * 2
7 2 True 2 1 * 2 2e itération
8–9 3 True 4 1 * 2 * 2
7 3 True 4 1 * 2 * 2 3e itération
8–9 4 True 8 1 * 2 * 2 * 2
7 4 True 8 1 * 2 * 2 * 2 4e itération
8–9 5 True 16 1 * 2 * 2 * 2 * 2
7 5 False 16 1 * 2 * 2 * 2 * 2
10 5 False 16 1 * 2 * 2 * 2 * 2

TABLE 5.7 – Trace du programme de l’exemple 5.13, en supposant que x=2 et n=4. La trace
démarre de ce fait ligne 5.


5.7 Imbrication de boucles 63

5.7 Imbrication de boucles


 Exemple 5.14 — Tables de multiplication. On souhaite afficher les tables de multiplication par
2 et 3. Pour cela, on va utiliser une boucle itérant sur les valeurs du multiplicateur 2 et 3. Dans cette
boucle, on va placer une deuxième boucle itérant de 1 à 9, de façon à afficher une table chaque
multiplicateur considéré.

1 n = 2
2 while n <= 3:
3 i = 1
4 while i <= 9:
5 print(i, "*", n, "=", i * n)
6 i += 1
7 n += 1
8 print("fin")

L’affichage produit est alors :


2 * 2 = 4
3 * 2 = 6
4 * 2 = 8
5 * 2 = 10
6 * 2 = 12
7 * 2 = 14
8 * 2 = 16
9 * 2 = 18
1 * 3 = 3
2 * 3 = 6
3 * 3 = 9
4 * 3 = 12
5 * 3 = 15
6 * 3 = 18
7 * 3 = 21
8 * 3 = 24
9 * 3 = 27
fin

5.8 Exercices supplémentaires sur les boucles


Exercice 5.3 — Dessin d’étoiles. Dans la même veine que l’exercice 5.1, écrivez un pro-
gramme permettant d’afficher un carré qui ne soit pas rempli. Par exemple, un carré de côté 4
serait :
****
* *
* *
****
De même, un carré de côté 6 serait :
64 Chapitre 5. Structures répétitives

******
* *
* *
* *
* *
******

La dimension du carré est demandée à l’utilisateur. On accepte uniquement des longueurs


supérieures ou égales à 2 (1 est un peu « pathologique »).


Exercice 5.4 — Dessiner un losange. Toujours dans la même série (ces exercices permettent
de bien acquérir les mécanismes de manipulation de variable de contrôle d’une boucle for),
écrivez un programme permettant d’afficher un losange (ou plutôt un carré pivoté de 45°, à partir
de la longueur de son côté saisie par l’utilisateur.
Par exemple, pour un côté de longueur 5 on obtiendrait :
*
* *
* *
* *
* *
* *
* *
* *
*
La longueur minimale acceptée sera de 2. 

5.9 Annexes
5.9.1 Solutions des exercices

Solution de l’exercice 5.1 Le dessin peut être produit par le programme suivant :

n = 6
for i in range(n):
print((n-i)*'*')

Autre solution :

n = 6
for i in range(n,0,-1):
print(i*'*')

Solution de l’exercice 5.2 Voici une façon de réécrire le programme de dessin d’étoiles en
utilisant une boucle while au lieu d’une boucle for :
5.9 Annexes 65

n = 6
i = 0
while i < n:
print((n-i)*'*')
i += 1

Ou encore :

n = 6
i = n
while i > 0:
print(i*'*')
i -= 1

Solution de l’exercice 5.3 Voici une solutoion possible pour le dessin de carrés.

1 """
2 Affichage de carrés.
3 """
4
5
6 def main():
7 """programme principal"""
8 longueur = int(input("Saisissez la longueur d'un côté du carré : "))
9 while longueur < 2:
10 longueur = int(input("Saisissez la longueur d'un côté du carré : "))
11
12 for i in range(longueur):
13 if i == 0 or i == (longueur - 1):
14 # première et dernière ligne : pleine
15 print("*"*longueur)
16 else:
17 # autres lignes : "creuses"
18 print("*", " " * (longueur-2), "*", sep='')
19
20
21 if __name__ == "__main__":
22 main()

Quelques remarques :
— Remarquez la façon dont on repère la première et la dernière ligne en utilisant l’indice de
la boucle (ligne 13).
— Notez que le cas où longueur égale 1 se traite très bien. On fera une seule itération de la
boucle for (avec i valant zéro), et la condition de la ligne 13 sera vraie. On affichera au
final une seule étoile.
— Notez l’utilisation de l’argument sep='' pour éviter que print n’affiche un espace entre
66 Chapitre 5. Structures répétitives

chaque argument.
Voici une trace du programme, en supposant que l’exécution commence à la ligne 12 avec
longueur ayant pour valeur 5 :
ligne i affichage commentaire
12 0 1re itération
13 0 condition vraie (car i == 0)
15 0 *****
12 1 2e itération
13 1 condition fausse (i6= 0 et i6=longueur-1)
18 1 *␣␣␣*
12 2 3e itération
13 2 condition fausse (i6= 0 et i6=longueur-1)
18 2 *␣␣␣*
12 3 4e itération
13 3 condition fausse (i6= 0 et i6=longueur-1)
18 3 *␣␣␣*
12 4 5e itération
13 4 condition vraie (car i == longueur-1)
15 4 *****

Solution de l’exercice 5.4 Une solution possible au dessin de losange :


5.9 Annexes 67

1 """
2 Affichage d'un losage de la longueur saisie.
3 """
4
5
6 def main():
7 """Programme Principal."""
8 longueur = int(input("Saisissez la longueur d'un côté : "))
9 while longueur < 2:
10 longueur = int(input("Saisissez la longueur d'un côté : "))
11
12 # partie croissante
13 for i in range(longueur):
14 # espaces en début de ligne
15 print(" "*(longueur - 1 - i), end="")
16 if i == 0:
17 # première ligne : une seule étoile
18 print("*")
19 else:
20 # autre ligne
21 print("*", " "*(2 * i - 1), "*", sep='')
22
23 # partie décroissante
24 for i in range(longueur-1, 0, -1):
25 # espaces en début de ligne
26 print(" "*(longueur - i), end="")
27 if i == 1:
28 # dernière ligne : une seule étoile
29 print("*")
30 else:
31 # autre ligne
32 print("*", " "*(2 * (i - 1) - 1), "*", sep="")
33
34
35 if __name__ == '__main__':
36 main()

Quelques commentaires :
— La première boucle for va afficher la moitié supérieure du losange (de la pointe jusqu’à
la ligne où il est le plus large). La seconde boucle for va afficher la partie qui va en se
rétrécissant, jusqu’à la pointe du bas.
— La première boucle fait varier l’indice i de façon croissante, de 0 jusqu’à longueur-1
— La seconde boucle fait varier l’indice i de façon décroissante, de longueur-1 jusqu’à 1
(rappelez vous que l’indice de fin d’un range est toujours exclu).
— Notez l’utilisation de l’argument end="" de la fonction préféfinie print pour éviter le
passage à la ligne en fin d’affichage.
— Notez l’utilisation de l’argument sep='' pour éviter que print n’affiche un espace entre
chaque argument.
68 Chapitre 5. Structures répétitives

— Notez que les print des lignes 15 et 26 ne passent pas à la ligne après l’affichage,
puisqu’ils servent à afficher les espaces en début de ligne.
Voici une trace du programme, en supposant qu’on comment l’exécution à la ligne 13, avec
une valeur de 4 pour la variable longueur.
ligne i affichage commentaire
13 0 1re itération première boucle
15 0 ␣␣␣ (4 − 1 − 0) espaces
16 0 condition vraie
18 0 *\n \n : passage à la ligne effectué par le print
13 1 2e itération
15 1 ␣␣ (4 − 1 − 1) espaces
16 1 condition fausse
21 1 *␣*\n (2 × 1) − 1 espaces
13 2 3e itération
15 2 ␣ (4 − 1 − 2) espaces
16 2 condition fausse
21 2 *␣␣␣*\n (2 × 2) − 1 espaces
13 3 4e itération
15 3 (4 − 1 − 3) = 0 espaces !
16 3 condition fausse
21 3 *␣␣␣␣␣*\n (2 × 3) − 1 espaces
24 3 1re itération seconde boucle
26 3 ␣ 4 − 3 espaces
27 3 condition fausse
32 3 *␣␣␣*\n (2 × (3 − 1) − 1 espaces
24 2 2e itération
26 2 ␣␣ 4 − 2 espaces
27 2 condition fausse
32 2 *␣*\n (2 × (2 − 1) − 1 espaces
24 1 3e itération
26 1 ␣␣␣ 4 − 1 espaces
27 1 condition vraie
29 1 *\n
6. Procédures et fonctions

6.1 Définition
Définition 6.1.1 — Fonction. Une fonction est un bloc, une suite d’instructions, autonome
décrivant un calcul ou une tâche dans le but de structurer le programme en tâches simples. Elle :
— possède un nom ;
— possède éventuellement des paramètres d’entrée servant à faire varier les calculs ; ces
paramètres sont identifiés par un nom et un ordre ;
— renvoie une unique valeur (dépendant ou non de ses paramètres) représentant le résultat
de la fonction.
Elle se décrit par une signature de la forme nom_de_fonction(param1, param2, ...,
paramN).

 Exemple 6.1 — exemples de fonctions fournies par Python.


— cos(x) est la fonction dont le nom est cos. Elle possède un paramètre x, et renvoie la valeur
du cosinus de son paramètre.
— max(a,b) est la fonction dont le nom est max. Elle possède deux paramètres a et b, et renvoie
la valeur la plus grande entre a et b.


6.2 Déclaration d’une fonction


Nous avons vu jusqu’ici (section 3.6) que le langage Python fournit un certain nombre de
fonctions prédéfinies. Python, comme tous les langages de programmation, permet aussi de définir
ses propres fonctions.
Définition 6.2.1 — Éléments de déclaration d’une fonction. La déclaration d’une fonction
met en œuvre les éléments suivants :
— le nom de la fonction ;
— la liste des paramètres de la fonction ;
— une ou plusieurs préconditions (optionnelles) qui sont des expressions booléennes préci-
70 Chapitre 6. Procédures et fonctions

sant les conditions dans lesquelles la fonction peut être appelée ;


— La description, optionnelle mais obligatoire, qui est la documentation de la fonction ;
— Le code, c’est à dire la séquence d’instructions résolvant le problème ;
— le retour, ou renvoi, indiquant la valeur renvoyée par la fonction.
La syntaxe de la déclaration d’une fonction est la suivante :

def nom(param1, param2, ..., paramN):


[""" commentaires """] # documentation
[assert type(param) is ...] # préconditions

instruction # code
instruction
...
return [valeur] # renvoie la valeur de retour
# et sort de la fonction
# fin de la fonction

Y
— L’indentation définit le bloc de la fonction.
— L’exécution de return stoppe le flux d’instructions et force la sortie de la fonction.
— Si return n’est suivi d’aucune valeur, la fonction renvoie None.

 Exemple 6.2 — fonction à un paramètre : factorielle. La fonction factorielle et son unique


paramètre est déclarée par :
def factorielle(n):
"""Calcule et renvoie la factorielle du nombre entier positif n, valant n!"""
res = 1
for i in range(1, n+1):
res *= i
return res # valeur de retour

On peut par exemple l’appeler de la façon suivante :

res = factorielle(4)
print("4! =", res)
res = factorielle(3)
print("3! =", res)

Ce qui produit l’affichage :


4! = 24
3! = 6


   Pour aller plus loin : Notez que dans le commentaire décrivant la fonction, on précise
que n doit être un entier positif, mais on ne le vérifie pas dans la fonction. Que se passe-t-il si on
ne respecte pas ces conditions ? Par exemple, si on appelle la fonction avec une valeur flottante ?
Essayons directement à partir de ’interpréteur Python :
>>> factorielle(4.5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
6.2 Déclaration d’une fonction 71

File "/home/wurbel/src/python/ExemplesCours/factorielle.py", line 4, in factorielle


for i in range(1, n+1):
TypeError: 'float' object cannot be interpreted as an integer

Notez l’erreur de type signalée : l’interpréteur nous indique qu’il ne peut pas interpréter une valeur
flottante en tant qu’entier. On obtient donc une erreur signalée par le langage.
Essayons maintenant d’utiliser un entier négatif, ce qui n’a pas de sens.

>>> factorielle(-4)
1

Surprenant ! On obtient un résultat, mais celui-ci n’a aucun sens puisque la factorielle n’est définie
que pour des entiers positifs.
Idéalement, il faudrait se prémunir contre ces mauvais usages de la fonction factorielle,
c’est à dire vérifier que la valeur du paramètre n :
— est un entier,
— est positive.
On peut ajouter deux préconditions pour cela :
1 def factorielle(n):
2 """Calcule et renvoie la factorielle du nombre entier positif n, valant n!"""
3 assert type(n) is int
4 assert n > 0
5
6 res = 1
7 for i in range(1, n+1):
8 res *= i
9 return res # valeur de retour

La première précondition à la ligne 3 vérifie que la valeur passée au paramètre n est bien un entier.
La seconde précondition vérifie que cette valeur est positive. En cas de non respect d’une de ces
contitions, l’exécution est immédiatement interrompue :
>>> factorielle(4.5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/wurbel/src/python/ExemplesCours/factorielle.py", line 3, in factorielle
assert type(n) is int
AssertionError
>>> factorielle(-4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/wurbel/src/python/ExemplesCours/factorielle.py", line 4, in factorielle
assert n > 0
AssertionError

On remarque que :
— lorsqu’on essaie de passer une valeur flottante, c’est la première précondition qui n’est pas
respectée ;
— lorsqu’on essaie de passer un entier négatif, c’est la seconde précondition qui n’est pas
respectée.
Les préconditions sont un moyen puissant de se prémunir contre les erreurs dans les programmes.
N’hésitez pas à vous en servir.
 Exemple 6.3 — Fonction à deux paramètres. La fonction somme2, possédant deux paramètres
a et b, est déclarée de la façon suivante :
72 Chapitre 6. Procédures et fonctions

def somme2(a, b):


"""Calcule et renvoie la somme de deux nombres (ou de deux chaînes) a
et b"""
total = a + b
return total

Elle peut être appelée par exemple par :

res = somme2(10, 2)
print("10+2 vaut :", res)
res = somme2('a', 'b')
print("a+b vaut :", res)

Ce qui produit l’affichage suivant :


10+2 vaut : 12
a+b vaut : ab


Y    : Cette fonction est un exemple de généricité : elle peut être utilisée avec n’importe
quel type d’objet, pourvu que l’addition + soit définie.

6.3 Fonctions à plusieurs points de retour


Une fonction possède obligatoirement au moins une instruction return, qui déclenche la fin
de la fonction, et le retour à l’instruction appelante, avec pour valeur de retour celle indiquée par
l’instruction return.
L’instruction return peut apparaitre plusieurs fois. Bien entendu, une seule sera évaluée
puisque l’exécution de cette instruction déclenche la fin de la fonction et le retour à l’appelant.
 Exemple 6.4 — strictement plus grand. La fonction suivante illustre l’utilisation de multiples
instructions return.

def strctmax(a, b):


"""
Renvoie la valeur du paramètre strictement le plus grand, None
sinon.
"""
if a > b:
return a
elif b > a:
return b
else:
return

Exemples d’appels :

res = strctmax(1, 2)
print("strctmax de 1 et 2 :", res)
6.3 Fonctions à plusieurs points de retour 73

res = strctmax(3, 1)
print("strctmax de 3 et 1 :", res)
res = strctmax(4, 4)
print("strctmax de 4 et 4 :", res)

L’affichage produit est :


strctmax de 1 et 2 : 2
strctmax de 3 et 1 : 3
strctmax de 4 et 4 : None

! L’utilisation de multiples instructions return est généralement une mauvaise pratique.


En effet, plus on multiplie les instructions return, plus il devient compliqué d’être certain
qu’on a bien traité tous les cas !

Par exemple si on reprend le code de la fonction strctmax :

def strctmax(a, b):


"""
Renvoie la valeur du paramètre strictement le plus grand, None
sinon.
"""
if a > b:
return a
elif b > a:
return b
else:
return
# Est-on certain qu'on ne passera jamais ici ?

Il est souvent plus prudent, et généralement sans incidence sur l’efficité de l’algorithme, de n’avoir
qu’une seule instruction return, située à la fin de la fonction. Ainsi, on peut réécrire la fonction
strctmax de la façon suivante :

def strctmax(a, b):


"""
Renvoie la valeur du paramètre strictement le plus grand, None
sinon.
"""
res = None
if a > b:
res = a
elif b > a:
res = b
return res
74 Chapitre 6. Procédures et fonctions

6.4 Portée des variables


6.4.1 Notion de portée
Définition 6.4.1 — Contexte de nommage. L’exécution d’un programme s’appuie sur un
contexte de nommage des variables et sur la mémoire qui stocke leur valeur.
— Le programme principal utilise le contexte principal.
— Un appel de fonction crée un contexte local (qui est propre à la fonction) dans lequel sont
déclarés les paramètres et les variables de cette fonction :
— Ce contexte local est effacé lors du retour de la fonction (instruction return). il
n’existe plus par la suite.
— Il est recréé à chaque nouvel appel de la fonction.
— les paramètres reçoivent une copie des arguments d’appel (cf. défintions 3.6.1 et
3.6.2 page 39 pour un rappel de vocabulaire sur la différence entre paramètre et
argument.
— Le contexte principal et les contextes locaux sont complètement séparés. Il n’y a pas
d’interférences entre eux : on dit que la portée des variables d’une fonction est locale à la
fonction., c’est-à-dire que les variables n’existent que lors de l’appel de la fonction. Elles
peuvent donc avoir le même nom que des variables du programme principal sans conflit.
— La mémoire est partagée par le programme principal et les fonctions.

6.4.2 Contexte local d’une fonction


 Exemple 6.5 Considérez la fonction suivante :

def puissance():
nbr = 3
puiss = 2
res = nbr ** puiss
return res

appelée dans le programme principal suivant :

nbr = 1
res = puissance()

— Le contexte (figure 6.1) n’existe qu’au moment de l’évaluation de la fonction. La variable


locale nbr diffère donc de nbr, de même que res diffère de res.
— L’objet en mémoire, renvoyé par la fonction, est celui récupéré dans le programme principal,
et donc affecté ici à res.

6.4.3 Contexte d’une fonction avec paramètres


 Exemple 6.6 Considérez la fonction :

def somme(a, b):


a = 3
res = a + b
return res

appelée ainsi :
6.4 Portée des variables 75

Appel : puissance()

Contexte Contexte
principal Mémoire
local

nbr 1
3 nbr
2 puiss
res 9 res

return res

F IGURE 6.1 – Contexte local d’appel à une fonction sans paramètre

a = 1
b = 2
res = somme(a, b)
mais = a + b

Appel : somme(a, b)

Contexte Contexte
principal Mémoire
local

3
a 1 % a
b 2 b
res 5 res
mais 3

return res

F IGURE 6.2 – Contexte local d’appel à une fonction avec paramètres

— Lors de l’appel à la fonction somme (cf. figure 6.2), les paramètres a et b (n’existant que dans
le contexte local) référencent les mêmes objets que a et b.
— Toute modification des paramètres (ou plus précisément, toute réaffectation des objets
désignés par les paramètres) dans la fonction n’aura d’impact que dans a fonction, pas dans
le programme principal, puisque a et a ne désignent plus les mêmes objets à la fin de la
fonction.
76 Chapitre 6. Procédures et fonctions

6.5 Chaînage de fonctions


Une fonction peut appeler une autre fonction.
 Exemple 6.7 La fonction somme4 utilise la fonction somme2 pour additionner ses quatre para-
mètres.

def somme4(a, b, c, d):


"""
calcule la somme des 4 paramètres en utilisant somme2
"""
res1 = somme2(a, b)
res2 = somme2(c, d)
res = somme2(res1, res2)
return res

def somme2(a, b):


res = a + b
return res

Exemple d’appels :

res = somme4(1, 2, 3, 4)
print("1+2+3+4 :", res)
res = somme4('a', 'b', 'c', 'd')
print("a+b+c+d :", res)

L’exécution de ce fragment de programme produit l’affichage suivant :


1+2+3+4 : 10
a+b+c+d : abcd

7. Listes

7.1 Les listes


Définition 7.1.1 — Listes. Les listes (classe list) appartiennent à une catégorie particulière
des objets Python : les séquences. Ce sont des collections ordonnées d’éléments identifiées
par une référence (stockée dans une variable). Chaque élément de la liste peut-être d’un type
quelconque.
Les listes sont des objets mutables, ce qui signifie qu’on pourra modifier en mémoire les
éléments de la collection. Les éléments d’une liste, tout comme sa longueur, pourront donc
évoluer durant l’exécution d’un programme.

Définition 7.1.2 — Syntaxe de déclaration. Une liste de N éléments se déclare ainsi :

liste = [elem0, elem1, ..., elemN_1]

La variable liste référence alors les éléments elem0, elem1, ..., elemN_1 en mé-
moire, en leur attribuant un ordre : elem0 est le premier élément, elem1 le second. . . et elemN_1
le dernier. La figure 7.1 illustre cette situation.

Le nombre d’éléments d’une liste est renvoyé par la fonction len.


 Exemple 7.1 — longueur d’une liste. Le programme suivant :

prenoms = ["Éric","Hugo","Sarah"]
print("longueur =", len(prenoms))

produit l’affichage :
longueur = 3


78 Chapitre 7. Listes

Contexte
principal Mémoire

liste [0] elem0


[1] elem1
[2] elem2
..
.
[N − 1] elemN_1

F IGURE 7.1 – Liste d’éléments en mémoire et leurs indices

7.2 Accès aux éléments


7.2.1 Éléments et indices
Définition 7.2.1 — Indices des éléments d’une liste. Les éléments d’une liste liste =
[elem0, elem1, ..., elemN_1] étant ordonnés, chaque élément de la liste est lié à un
indice. L’indice est la position de l’élément dans la liste : 0 pour elem0, 1 pour elem1. . . et
len(liste)-1 pour le dernier élement elemN_1.

Définition 7.2.2 — Accès aux éléments d’une liste. Pour un indice i donné, la syntaxe
liste[i] accède à l’élément d’indice i de la liste, en lecture comme en écriture.

! Si l’indice n’est pas compris entre 0 et len(liste)-1, l’expression liste[i] peut provo-
quer une erreur de type IndexError: list index out of range.

 Exemple 7.2 — manipulation de listes. Le programme :

liste = [1, 2, "spam"]


print("liste=", liste, "type=", type(liste))
elmt = liste[2] # accès à l'élément d'indice 2
print("elmt=", elmt)
liste[0] = 'eggs' # modif de l'élément d'indice 0
print("liste=", liste)
liste[1] = 3.5
print("liste=", liste)
l = len(liste)
print("longueur=", l)

produit l’affichage suivant :

liste= [1, 2, 'spam'] type= <class 'list'>


elmt= bob
liste= ['eggs', 2, 'spam']
liste= ['eggs', 3.5, 'spam']
longueur= 3

Le contexte et la mémoire correspondant à l’exemple est décrit dans la figure 7.2. 


7.2 Accès aux éléments 79

Contexte
principal Mémoire

liste [0] 1 'eggs'


[1] 2 3.5
[2] 'spam'

F IGURE 7.2 – un exemple de liste en mémoire

Exercice 7.1 — Accès aux éléments d’une liste. Soit la liste fruits = ['pomme', 'poire',
'banane', 'orange']. Indiquez quel est le résultat affiché par les instructions print sui-
vantes :

print(fruits[0])
print(fruits[2])
print(fruits[4])

Exercice 7.2 — Modification des éléments d’une liste. Soit la liste mesures_temp =
[13.4, 13.0, 9.5, 13.0, 14.3]. Quel est l’état de la liste après chacune des affectations
suivantes :

mesures_temp[1] = 13.2
mesures_temp[4] = 14.8
mesures_temp[5] = 17.2

7.2.2 L’opérateur in
Définition 7.2.3 — Opérateur in. L’opérateur in permet de tester l’appartenance d’une valeur
à une liste.
— Pour tester si une valeur est égale à l’un des éléments d’une liste, on utilise l’expression
valeur in liste.
— Pour tester si une valeur est différente de tous les éléments d’une liste, on utilise l’expres-
sion valeur not in liste.
 Exemple 7.3 — opérateur in. Le programme

liste = [1, 'a', 'aba', 2, 'a']


test1 = ('a' in liste)
print("a dans liste?", test1)
test2 = ('b' in liste)
print("b dans liste?", test2)
test3 = (0 not in liste)
print("0 pas dans liste?", test3)
test4 = (2 not in liste)
80 Chapitre 7. Listes

print("2 pas dans liste?", test4)

Produit l’affichage suivant :


a dans la liste? True
b dans la liste? False
0 pas dans la liste? True
1 pas dans la liste? False

Exercice 7.3 — Opérateur in et interrogation de données. Écrivez une fonction cherche(art,


liste_art) qui recherche une article art (une chaîne de caractères) dans une liste liste_art
de chaînes de caractères représentant une liste d’articles. La fonction renvoie True si l’article
est trouvé, False.
Écrivez ensuite un programme principal qui demande à l’utilisateur de saisir un article à
chercher et qui lui indique si cet article existe ou pas. On demandera ensuite à l’utilisateur s’il
souhaite continuer à l’aide d’une question dont la réponse est de type oui/non.
On imagine une liste d’articles pouvant servir d’exemple :

articles = ["écran", "souris", "ssd 1To", "ssd 2To"]

7.3 Fonctions et méthodes pour l’objet list


7.3.1 Méthodes modifiant les éléments d’une liste
Définition 7.3.1 Les méthodes suivantes traitent les éléments d’une liste et les modifient
directement en mémoire :
1. Méthodes dont la valeur de retour est None :
— liste.append(elem) : ajoute elem à la fin de la liste.
— liste.sort() : trie la liste par ordre croissant.
2. Méthodes avec une valeur de retour exploitable :
— e = liste.pop(i) : retire et renvoie dans e l’élément d’indice i de la liste ; si
i n’est pas précisé, retire et renvoie le dernier élément de la liste.

 Exemple 7.4 — manipulation de listes. Le programme

liste = [1, 2, 'a']


print("1> liste=", liste)
liste.append(3)
# ajoute 3 en fin de liste
print("2> liste=", liste)
e = liste.pop(2)
# retire l'element d'indice 2 et le renvoie
print("3> liste=", liste, "e=", e)

produit l’affichage suivant :


7.3 Fonctions et méthodes pour l’objet list 81

1> liste= [1, 2, 'a']


2> liste= [1, 2, 'a', 3]
3> liste= [1, 2, 3] e= a

Exercice 7.4 — Saisie et tri de liste. Écrivez un programme qui demande à l’utilisateur de
saisir un entier qui est ajouté dans une liste. La saisie se termine lorsque l’utilisateur saisit la
valeur 0.
Le programme trie ensuite cette liste et l’affiche. 

7.3.2 Méthodes utilisant les éléments d’une liste


Définition 7.3.2 — méthodes utilisant la liste (sans modification des élements).
— i = liste.index(valeur) : renvoie l’indice i de la première occurrence de valeur
dans liste.
— n = liste.count(valeur) : renvoie le nombre total d’occurrences de valeur dans
liste
 Exemple 7.5 — manipulation de listes. Le programme

liste = [1, 1, 'a', 'b', 'a']


nbre = liste.count('a')
# compte le nombre de 'a'
print("nombre de 'a'=", nbre)
ia = liste.index('a')
print("indice du 1er 'a'=", ia)
i1 = liste.index(1)
print("indice du 1er 1=", i1)
print("liste=", liste)

produit l’affichage suivant :


nombre de 'a'= 2
indice du premier 'a'= 2
indice du premier 1= 0
liste= [1, 1, 'a', 'b', 'a']

7.3.3 Fonctions sur les listes numériques


Définition 7.3.3 — Fonctions propres aux listes numériques. Lorsqu’une liste ne contient
que des valeurs numériques, (int ou float) :
— val = min(liste) : valeur minimum dans la liste
— val = max(liste) : valeur maximum dans la liste
— val = sum(liste) : somme des éléments de la liste
 Exemple 7.6 — min, max et somme. Le programme

liste = [5, 4, 3, 2, 1]
val_min = min(liste)
print("val_min=", val_min)
82 Chapitre 7. Listes

val_max = max(liste)
print("val_max=", val_max)
s = sum(liste)
print("somme=", s)

produit l’affichage suivant :


val_min= 1
val_max= 5
somme= 15


7.3.4 Autres méthodes sur les listes


Définition 7.3.4 La classe list propose un grand nombre de méthodes de traitement des listes
(voir la documentation officielle. Parmi celles-ci, citons :
— liste.extend(liste2) : ajoute la liste2 d’éléments à la fin de la liste.
— liste.insert(i, elem) : insère elem dans liste à l’indice i.
— liste.remove(x) : retire la première occurrence de x dans la liste.
— liste.reverse() : renverse l’ordre des éléments dans la liste
 Exemple 7.7 — autres méthodes. Le programme

liste = [1, 2, 'a', 3]


liste.insert(3, 2)
print("4> liste=", liste)
liste.remove(2)
print("5> liste=", liste)
liste.reverse()
print("6> liste=", liste)
liste.extend(['a', 'b'])
print("7> liste=", liste)

produit l’affichage suivant :

4> liste= [1, 2, 'a', 2, 3]


5> liste= [1, 'a', 2, 3]
6> liste= [3, 2, 'a', 1]
7> liste= [3, 2, 'a', 1, 'a', 'b']

7.4 Parcours de listes


7.4.1 Notion d’itérable
Définition 7.4.1 — Objet itérable.
— Une liste est un objet itérable, c’est-à-dire une collection d’éléments dont on peut prendre
(ou parcourir) les éléments un à un.
— Comme elle contient des éléments ordonnés, accessibles par leur indice allant de 0 à
len(liste) - 1, le parcours naturel consiste à prendre les éléments un par un dans
l’ordre croissant des indices.
7.4 Parcours de listes 83

— La boucle for est le choix privilégié pour parcourir une liste.

7.4.2 Parcours itératif de tous les éléments


Parcours itératif avec une boucle for
Lorsque tous les élements d’une liste doivent être parcourus, deux syntaxes de parcours sont
possibles.
Définition 7.4.2 — Parcours d’une liste par le biais des indices. La structure de boucle
suivante permet d’itérer sur tous les indices d’une chaîne liste :

for i in range(len(liste)):
# instruction manipulant liste[i]
# ...
# suite du programme

Définition 7.4.3 — Parcours d’une liste par le biais des éléments. La structure de boucle
suivante permet d’itérer sur tous les éléments d’une liste :

for elt in liste:


# instruction manipulant elt
# ...
# suite du programme

À chaque itération, elt prend pour valeur un des élements de la liste (du premier au dernier
dans l’ordre des indices), et exécute les instructions.

Le parcours via les indices et les parcours via les éléments sont équivalents, elt valant
liste[i].
 Exemple 7.8 — Affichage de liste. Pour une même liste liste = [1, 2, 3, 4] :
1. Parcours par indice :

for i in range(len(liste)):
print(liste[i], '/', end="")
print("fin")

2. Parcours par élements :

for elt in liste:


print(elt, '/', end="")
print("fin")

Les deux parcours sont équivalents et produisent l’affichage :

1 /2 /3 /4 /fin


Y Le parcours par les indices est à privilégier si on a besoin de l’indice dans les traitements
effectués dans la boucle. Dans le cas contraire, le parcours par éléments est plus efficace.

 Exemple 7.9 — affichage des éléments précédés de leur indice. Pour une même liste
liste = ['a', 1, 'b'] :
84 Chapitre 7. Listes

1. Parcours par indices :

for i in range(len(liste)):
print(i, ':', liste[i], '/', end="")
print("fin")

2. Parcours par éléments :

indice = 0 # Création d’un compteur d’éléments


for elmt in liste:
print(indice, ':', elmt, '/', end="")
indice += 1 # Incrémentation compteur
print("fin")

Les deux parcours sont équivalents et produisent l’affichage :

0 : a /1 : 1 /2 : b /fin

Y La boucle for i in range(n) cache un parcours itératif : la fonction range renvoie


un objet (de type range) correspondant à la collection ordonnée itérable 0, 1, 2, ...,
n-1 (attention, ce n’est pas une liste). Cette collection étant itérable, la boucle for en parcourt
les éléments, du premier (0) jusqu’au dernier (n-1).

Y Dans une boucle itérable de type for elm in liste, les éléments à parcourir sont évalués
à l’entrée dans la boucle for ; ils ne changeront pas au cours des itérations, même si la liste
évolue. Par exemple,

liste = [1, 2]
for elt in liste:
liste.append(elt + 1)

boucle deux fois, (parcours des éléments 1 et 2) et se termine avec liste valant [1, 2, 2,
3].

Exercice 7.5 — Affichage des éléments d’indice impair. Écrivez un programme qui affiche
les éléments d’indice impair d’une liste. Testez avec la liste [1, 35, -10, 100, 2, 5, 21].
Avec la liste de test, l’affichage produit sera
35 100 5


Exercice 7.6 — Affichage des éléments impairs. Écrivez un programme qui affiche les
éléments impairs d’une liste d’entiers. Testez avec la liste [1, 35, -10, 100, 2, 5, 21].
Avec la liste de test, l’affichage sera :
1 35 5 21

7.5 Construire une liste 85

7.4.3 Parcours d’une partie des éléments avec une boucle while
Lorque l’on souhaite ne parcourir qu’une partie des éléments d’une liste, par exemple tant
qu’une condition_booleenne n’est pas vérifiée, on utilise une boucle while :

i = 0 # compteur d'indice
while i < len(liste) and condition_booleenne:
# instruction portant sur liste[i]
# ...
# suite_du_programme

Y La condition booleenne doit être précédée d’un test vérifiant que la fin de la liste n’est
pas atteinte.

 Exemple 7.10 — parcours jusqu’au mot "fin". Le programme

liste = ['a', 'b', 'fin', 'd', 1]


i = 0
while i<len(liste) and liste[i]!="fin":
print("indice", i, ":", liste[i], "ne vaut pas fin")
i = i+1
print("indice", i, ":", liste[i], "vaut fin")
print("fin")

itère la boucle deux fois et produit l’affichage suivant :


indice 0 : a ne vaut pas fin
indice 1 : b ne vaut pas fin
indice 2 : fin vaut fin
fin


7.5 Construire une liste


7.5.1 utilisation de append
Comme nous l’avons vu dans la section 7.3.1, la méthode liste.append(x) ajoute l’élément
x à la fin de la liste. On peut donc l’utiliser pour construire une liste en partant d’une liste vide
(liste = [] ou liste = list()), puis en ajoutant des éléments à l’aide d’une boucle while ou
for.
 Exemple 7.11 — construire une liste de 10 éléments valant 0. le programme

liste = list()
for i in range(10):
liste.append(0)
print(liste)

produit l’affichage suivant :

[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]


86 Chapitre 7. Listes

7.5.2 Opérateurs sur les listes


Nous avons déjà rencontré ces opérateurs qui agissent sur les chaînes de caractère. Les chaînes
de caractère étant des séquences tout comme les listes, il est donc logique qu’ils s’appliquent aussi
aux listes.
Définition 7.5.1 — opérateurs + et *. Les opérateurs suivants sont définis pour des opérandes
de type list :
— liste1 + liste2 concatène liste1 et liste2. Le résultat est une nouvelle liste.
— liste * n où liste est de la classe list et n est de la classe int. Duplique la liste n
fois.
 Exemple 7.12 — Construire une liste de 5 éléments valant 0, puis 5 éléments valant 1. Le
programme suivant

liste1 = [0]*5
liste2 = [1]*5
liste = liste1 + liste2
print liste

produit l’affichage suivant :

[0, 0, 0, 0, 0, 1, 1, 1, 1, 1]

! Ce procédé de construction ne doit être utilisé que pour des listes numériques ! Nous verrons
plus loin pourquoi (problématique des références associées à des objets mutables)

7.5.3 Fonction range


On rappelle que la fonction range(ini, fin_exclue, incr) renvoie une collection itérable
d’entiers (de type range) débutant à ini, finissant à fin_exclue (exclue), avec un incrément de
incr.
Définition 7.5.2 — transtypage en liste. Toute collection d’éléments peut être convertie en
liste en utilisant la fonction list qui renvoie les éléments de la collection dans une liste. Si la
collection est ordonnée, l’ordre sera respecté dans la liste obtenue.

 Exemple 7.13 — Construire une liste d’entiers de 5 à 20 par pas de 2. Le programme

collection = range(5, 21, 2)


liste = list(collection)
print(liste)

produit l’affichage suivant :

[5, 7, 9, 11, 13, 15, 17, 19]

7.5.4 Liste en intention


Les listes en intentions sont un mécanisme très puissant de construction des listes en python :
il permet de construire une liste en se basant sur une collection existante, en parcourant (en
itérant) tous les élements elt de la collection et :
7.6 Listes et fonctions 87

— en transformant chaque élément elt par une expression simple utilisant elt
— optionnellement en filtrant une sous-partie de la collection, sur la base d’une condition
sur l’élément condition_sur_elm.
Syntaxe :

liste = [ expression for elm in collection if condition_sur_elm ]

 Exemple 7.14 — liste en intention des 5 premiers cubes parfaits. La liste en intention

liste_cubes = [ elmt ** 3 for elmt in range(5) ]

est équivalente au programme suivant

liste_cubes = []
for elmt in range(5):
liste_cubes.append(elmt ** 3)

La liste obtenue dans les deux cas est [0, 1, 8, 27, 64]. 

 Exemple 7.15 — liste en intention des entiers inférieurs à 10 et non divisibles par 3. La
liste en intention

liste_ndiv3 = [elmt for elmt in range(10) id elmt % 3 != 0]

est équivalente à

liste_ndiv3 = []
for elmt in range(10):
if elmt % 3 != 0:
liste_ndiv3.append(elmt)

La liste obtenue dans les deux cas est [1, 2, 4, 5, 7, 8]. 

7.6 Listes et fonctions


Une liste (et tous ses éléments) étant référencée par une variable, elle peut servir aussi bien
de paramètre que de valeur de retour d’une fonction.

! Si vous passez une liste en paramètre à une fonction et que dans cette fonction vous modifiez
les éléments de la liste, les modifications seront visible du contexte appelant.

 Exemple 7.16 — les listes dans les fonctions. La fonction suivante prend une liste en paramètre
et renvoie une nouvelle liste.

def ajoute_un(liste):
"""
Construit une liste res, dont les éléments sont ceux
du paramètre liste, chacun ayant été incrémenté de 1.
"""
res = []
for elmt in liste:
88 Chapitre 7. Listes

res.append(elmt + 1)
return res

L’appel suivant :

liste = [1, 2, 3]
nouvelle_liste = ajoute_un(liste)
print(nouvelle_liste)

Produit l’affichage suivant :

[2, 3, 4]

7.7 Listes en deux dimensions


Les éléments d’une liste peuvent être eux même de type list. On parle alors de listes en deux
dimensions. L’accès à l’élément j de la i-ième liste se fait alors par la syntaxe liste[i][j].
 Exemple 7.17 — liste en deux dimensions. Soit la liste :

liste = [ [1, 2, 3 ],
['a', 'b', 'c'],
[1.1, 2.2, 3.3] ]

— liste[0] donne accès à la liste [1, 2, 3] ;


— liste[0][2] donne accès à la valeur 3 ;
— liste[1][2] donne accès à la valeur 'c' ;


7.8 Exercices supplémentaires


Exercice 7.7 — insertion dans une liste. Python fournit une méthode application à une liste l
l.insert(i, x) permettant d’insérer un élément x à l’indice i dans l. Si i dépasse le dernier
indice de la liste, l’élément x es tout simplement ajouté à la fin de la liste.
Pour continuer à vous familiariser avec la manipulation des indices sur les listes, en vous
servant uniquement de l’accès aux éléments et de la méthode append(e), écrivez une fonction
insere(l, i, x) qui insère l’élément x à l’indice i dans la liste l.
Écrivez aussi des tests unitaires à l’aide d’assert.
Exemples d’utilisation :
7.9 Annexes 89

l = [1, 2, 3]
insere(l, 1, 10)
print(l)
insere(l, 4, 100)
print(l)
insere(l, 10, 111)
print(l)
insere(l, 0, 333)
print(l)

Affichage produit :

[1, 10, 2, 3]
[1, 10, 2, 3, 100]
[1, 10, 2, 3, 100, 111]
[333, 1, 10, 2, 3, 100, 111]


7.9 Annexes
7.9.1 Solutions des exercices

Solution de l’exercice 7.1 Les instructions à exécuter sont :

1 fruits = ['pomme', 'poire', 'banane', 'orange']


2 print(fruits[0])
3 print(fruits[2])
4 print(fruits[4])

L’affichage produit par ces instructions est :


1 pomme
2 banane
3 Traceback (most recent call last):
4 File "acces-liste.py", line 4, in <module>
5 print(fruits[4])
6 IndexError: list index out of range

La ligne 1 de l’affichage correspond à la ligne 1 des instructions à exécuter. 'pomme' est bien
l’élément d’indice 0 de la liste fruits.
La ligne 2 de l’affichage correspond à la ligne 2 des instructions à exécuter. 'banane' est
bien l’élément d’indice 2 de la liste fruits.
Les lignes 3, 4, 5 et 6 de l’affichage correspondent à l’instruction print(fruits[4]). Il
s’agit d’une erreur de type IndexError. Le message indique list index out of range, ce
qui signifie que l’indice demandé (4), n’existe pas dans la liste fruits.

Solution de l’exercice 7.2 Les instructions exécutées sont :


90 Chapitre 7. Listes

1 mesures_temp = [13.4, 13.0, 9.5, 13.0, 14.3]


2 mesures_temp[1] = 13.2
3 mesures_temp[4] = 14.8
4 mesures_temp[5] = 17.2

L’affichage produit par ces instructions est

1 Traceback (most recent call last):


2 File "modif-liste.py", line 4, in <module>
3 mesures_temp[5] = 17.2
4 IndexError: list assignment index out of range

Les trois premières instructions se déroulent correctement. En particulier, les lignes 2 et 3, qui
mettent à jour respectivement des éléments d’indice 1 et 4 de la liste mesure_temp s’exécutent
sans problème.
Après l’exécution de la ligne 2, l’état de la liste est [13.4, 13.2, 9.5, 13.0, 14.3]
(l’élément d’indice 1 a été modifié).
Après l’exécution de la ligne 3, l’état de la liste est [13.4, 13.2, 9.5, 13.0, 14.8]
(l’élément d’indice 4 a été modifié).
En revanche, l’exécution de la ligne 4 déclenche une erreur (lignes 1, 2, 3 et 4 de l’affichage).
L’erreur est de type IndexError, et le message précise que c’est l’indice de la liste assignée
qui pose problème. En effet, cette liste possède 5 éléments, les indices des éléments vont dont
de 0 à 4.

Solution de l’exercice 7.3


Voici une solution possible pour ce programme. Notez qu’on utilise l’opérateur in non seule-
ment dans la fonction cherche_article(art, liste_art), mais aussi dans le traitement
des réponses de l’utilisateur lorsqu’on l’interroche sur son désir de continuer ou pas.
La fonction de recherche :

1 def cherche_article(art, liste_art):


2 """Cherche un article art (une chaine de caractères) dans une liste de
3 chaines de caractères liste_art. Renvoie True si elle trouve,
4 False sinon.
5
6 """
7 return art in liste_art

Le programme principal :
7.9 Annexes 91

8 def main():
9 """Programme principal. Recherche d'articles dans une liste
10 d'articles. La recherche est réitérée tant que l'utilisateur ne
11 veut pas terminer.
12
13 """
14 # la liste d'articles
15 articles = ["écran", "souris", "ssd 1To", "ssd 2To"]
16
17 encore = True
18 while encore:
19 # recherche et affichage du résultat
20 recherche = input("article à rechercher : ")
21 print("l'article", recherche, end=" ")
22 if cherche_article(recherche, articles):
23 print("a été trouvé")
24 else:
25 print("n'a pas été trouvé")
26
27 # question sur la poursuite
28 rep = ""
29 # on essaie d'etre tolérant sur la réponse !
30 while rep not in ["o", "O", "oui", "OUI", "Oui",
31 "n", "N", "non", "NON", "Non"]:
32 rep = input("Voulez-vous continuer ? ")
33 encore = rep in ["o", "O", "oui", "OUI", "Oui"]
34
35 print("Au revoir")
36
37 if __name__ == '__main__':
38 main()

Solution de l’exercice 7.4


Voici un programme possible :
92 Chapitre 7. Listes

1 """Saisie et tri d'une liste d'entiers."""


2
3 def main():
4 """Programme principal"""
5 # pas de valeurs au départ
6 lst = []
7 val = int(input("Saisissez un entier : "))
8 # tant que la valeur saisie n'est pas la valeur de sortie.
9 while val != 0:
10 lst.append(val)
11 val = int(input("Saisissez un entier : "))
12
13 # tri de la liste
14 lst.sort()
15
16 print(lst)
17
18 if __name__ == '__main__':
19 main()

Solution de l’exercice 7.5 Le programme suivant réalise l’affichage des éléments de la liste [1,
35, -10, 100, 2, 5, 21] d’indice impair. Notez qu’on est obligés d’utiliser un parcours
par les indices car on a besoin de tester la parité de l’indice à la ligne 8.

1 """Affichage des éléments d'indice impair d'une liste."""


2
3
4 def main():
5 """Programme principal"""
6 lst = [1, 35, -10, 100, 2, 5, 21]
7 for i in range(len(lst)):
8 if i % 2 != 0:
9 print(lst[i], end=' ')
10 print()
11
12
13 if __name__ == '__main__':
14 main()

Solution de l’exercice 7.6 Le programme suivant réalise l’affichage des éléments impair de
la liste [1, 35, -10, 100, 2, 5, 21]. Notez qu’ici, contrairement à l’exercice 7.5, on peut
se servir d’un parcours par éléments, car on a pas besoin de l’indice.
7.9 Annexes 93

1 """Affichage des éléments impairs d'une liste."""


2
3
4 def main():
5 """Programme principal"""
6 lst = [1, 35, -10, 100, 2, 5, 21]
7 for elem in lst:
8 if elem % 2 != 0:
9 print(elem, end=' ')
10 print()
11
12
13 if __name__ == '__main__':
14 main()

Solution de l’exercice 7.7 Examinons l’idée générale de l’algorithme en français (nous


n’avons pas étudié formellement la notation algorithmique en français par manque d’heures de
cours. Toutefois, elle se comprend aisément).
1: algorithme I NSÈRE
2: entrées :
3: l : liste
4: i : entier
5: x : objet quelconque
6: variables :
7: i : entier
8: j : entier
9: début
10: si i dépasse le dernier indice de l alors
11: ajouter x à la fin de l
12: sinon
13: ajouter l[longueur(l) − 1] à la fin de l
14: pour tout j ∈ {longueur(l) − 2, . . . , i + 1} faire
15: l[j] ← l[j − 1]
16: fin pour
17: l[i] ← x
18: fin si
19: fin algorithme
Commentons cet algorithme :
— lignes 3–6 : on a besoin de trois paramètres (la liste l, l’indice i d’insertion et l’élément x
à insérer.
— lignes 7 et 8 : dans l’algorithme en lui même, nous aurons besoin de deux variables
entières.
— lignes 10 & 11 : le cas où l’indice d’insertion dépasse le dernier indice de l est le plus
simple à résoudre : on ajoute l’élément x à la fin de la liste l.
— ligne 13–17 : on est dans le cas où l’indice d’insertion est un indice existant. cela signifie
qu’il va fallor décaler tous les éléments à partir de cet indice d’une position vers la droite.
94 Chapitre 7. Listes

C’est l’objet des lignes 13–16 :


— ligne 13 : on ajoute à la fin de l une copie du dernier élément (attention, à partir de
là la liste comprend un élément de plus !)
— ligne 14 : on va parcourir de façon décroissante tous les indices allant de longueur(l)−
2 (c’est à dire l’avant-dernier élément) jusqu’à i + 1 (c’est à dire l’indice situé juste
après l’indice d’insertion.
— ligne 15 : pour chacun de ces indices, on recopie l’élément immédiatement à gauche
vers l’élément d’indice courant.
— ligne 17 : la place est alors libre pour placer le nouvel élément.
La traduction en Python ne pose pas de problème majeur. On commence par déclarer le nom de
notre fonction ainsi que ses paramètres :

1 def insere(l, i, x):


2 """Insère l'élément x dans la liste l à l'indice i."""

La traduction du test de la ligne 10 et de l’action à réaliser à la ligne 11 quand le test est vrai
(ajout en fin de liste) ne posent pas de problème particulier non plus :

3 if i > len(l) - 1:
4 l.append(x)

la partie « sinon » de l’algorithme consiste en :


— l’ajout d’un élément à la fin, dupliquant le dernier élément

5 else:
6 l.append(l[len[l]-1])

— la boucle réalisant le décalage vers la droite des éléments (la différence de notation en
Python vient du fait que dans la fonction range, la borne d’arrivée est exclue. Dans
l’algorithme, cette borne d’arrivée est i + 1 :

7 for j in range(len(l)-2, i, -1):


8 l[j] = l[j-1]

— Enfin, on range l’élément à sa place :

9 l[i] = x

Voici le programme complet avec ses tests unitaires.


7.9 Annexes 95
96 Chapitre 7. Listes

1 def insere(l, i, x):


2 """Insère l'élément x dans la liste l à l'indice i."""
3 if i >= len(l):
4 l.append(x)
5 else:
6 l.append(l[len(l)-1])
7 # parcours de len(l)-2 à i+1 par pas de -1
8 for j in range(len(l)-1, i, -1):
9 l[j] = l[j-1]
10 l[i] = x
11
12 def unit_tests():
13 print("Running tests")
14 # index overflow => append
15 l = []
16 insere(l, 0, 10)
17 assert l == [10]
18
19 # index unreasonable overflow => still append !
20 l = []
21 insere(l, 1000, 10)
22 assert l == [10]
23
24 # appending in a non empty list
25 l = [1, 2, 3]
26 insere(l, 3, 10)
27 assert l == [1, 2, 3, 10]
28
29 # appending in a non empty list
30 l = [1, 2, 3]
31 insere(l, 1000, 10)
32 assert l == [1, 2, 3, 10]
33
34 # inserting in the middle of a non empty list
35 l = [1, 2, 3]
36 insere(l, 1, 10)
37 assert l == [1, 10, 2, 3]
38
39 # inserting before the last element of a non empty list
40 l = [1, 2, 3]
41 insere(l, 2, 10)
42 assert l == [1, 2, 10, 3]
43
44 # inserting at the beginning of a non empty list
45 l = [1, 2, 3]
46 insere(l, 0, 10)
47 assert l == [10, 1, 2, 3]
48
49 print("Tests successfully ended.")
50
51 if __name__ == "__main__":
52 unit_tests()
7.9 Annexes 97
8. Chaînes de caractères

8.1 Le type str


Définition 8.1.1 — Chaîne de caractères. Les chaînes de caractère (classe str) sont des
séquences contenant une collection (suite) ordonnée) de caractères, identifiée par une référence.

Les chaînes de caractères sont des objets non mutables, c’est à dire qu’on ne peut pas modifier
en mémoire les caractères de la chaîne, il faut en créer une nouvelle.
Définition 8.1.2 — Déclaration d’une chaîne de caractères. Une chaîne se déclare par
des guillemets ou apostrophes entourant la suite de caractères qu’elle contient : chaine
="c0 c1 c2 . . . cN−1 ". Chaque caractère est ordonné, et donc indiçable, dans le sens de la lec-
ture (de gauche à droite pour les langues européennes).

Définition 8.1.3 — Nombre de caractères. La fonction len(chaine) renvoie le nombre de


caractères présents dans la chaine.

8.2 Accès aux caractères


8.2.1 Caractères et indices
Définition 8.2.1 — Indices des caractères. Les caractères contenus dans une chaîne chaine
= "c0 c1 c2 . . . cN−1 " étant ordonnés, l’indice d’un caractère désigne sa position dans la chaîne : 0
pour c0 , 1 pour c1 , . . . et len(chaine)-1 pour le dernier caractère cN−1 .

La figure 8.1 illustre cette définition.

Contexte Mémoire

chaine c0 c1 c2 · · · cN−1
[0] [1] [2] · · · [N − 1]

F IGURE 8.1 – Chaîne de caractères en mémoire.


100 Chapitre 8. Chaînes de caractères

Définition 8.2.2 — Accès aux éléments d’une chaîne en lecture. Pour un indice i donné,
la syntaxe chaine[i] permet d’accéder en lecture au caractère d’indice i de la chaine.

! Il n’est pas possible de modifier ce caractère à l’aide d’une affectation comme chaine[i] =
carac, car une chaîne de caractères est un objet non mutable.

 Exemple 8.1 — accès aux éléments d’une chaîne de caractères. Le programme

chaine = "le début" # Déclaration


print("chaine=", chaine)
print("type=", type(chaine))
l = len(chaine)
print("longueur=", l)
c0 = chaine[0] # Lecture du 1er carac.
print("carac d’indice 0=", c0)
c3 = chaine[3] # Lecture du 4e carac.
print("carac d’indice 3=", c3)

produit l’affichage suivant :


chaine= le début
type= <class ’str’>
longueur= 8
carac d’indice 0= l
carac d’indice 3= d


Y Si l’indice n’est pas compris entre 0 et len(chaine)-1, l’expression chaine[i] peut


provoquer une erreur de type
IndexError: string index out of range

Y L’instruction chaine[0] = 'L' tentant de modifier le 1er caractère de la chaîne produit une
erreur de type
TypeError: ’str’ object does not support item assignment
car une chaîne de caractères n’est pas un objet mutable.

8.2.2 L’opérateur in
L’opérateur in fonctionne de façon similaire aux listes.
Définition 8.2.3 — Opérateur in. L’opérateur in permet de tester l’appartenance d’un caractère
(ou d’une sous-chaîne) à une chaîne de caractères.
— Pour tester si un caractère (ou une sous-chaîne) est présent dans une chaîne, on utilise
l’expression caractere in chaine (ou sous_chaine in chaine).
— Pour tester si un caractère (ou une sous-chaîne) n’est pas présent dans une chaîne, on
utilise l’expression caractere not in chaine (ou sous_chaine not in chaine).

 Exemple 8.2 — tests d’appartenance. Le programme :

chaine = "abcd..."
test1 = ('a' in chaine)
8.3 Manipulation de chaînes de caractères 101

print("a dans chaine?", test1)


test2 = ('d..' in chaine)
print("d.. dans chaine?", test2)
test3 = ('q' in chaine)
print("q dans chaine?", test3)
test4 = ('r' not in chaine)
print("r pas dans chaine?", test4)

produit l’affichage suivant :


a dans chaine? True
d.. dans chaine? True
q dans chaine? False
r pas dans chaine? True

8.3 Manipulation de chaînes de caractères


8.3.1 rappel : manipulations élémentaires

è Nous avons déjà rencontrés les opérateurs de manipulation chaînes de caractère suivants :
— chaine1 + chaine2 : concaténation
— chaine * n : n répétitions (avec concaténation)

 Exemple 8.3 — manipulation de chaînes. Le programme

chaine = "le début" # Déclaration


print("chaine=", chaine)
fusion = chaine + " et la fin" # Concaténation
print("fusion=", fusion)
chaine = chaine + " de tout" # Concaténation avec réaffectation
print("chaine=", chaine)

Produit l’affichage suivant :


chaine= le début
fusion= le début et la fin
chaine= le début de tout


8.3.2 Méthodes de la classe str


Les méthodes s’appliquant aux objets de la classe str exploitent les caractères de la chaîne
sans les modifier et ont toujours une valeur de retour exploitable.
Définition 8.3.1 — méthodes de test. Les méthodes suivantes renvoient un booléen :
— res = chaine.startswith(prefixe) : res vaudra True si la chaine commence par
le prefixe, False sinon.
— res = chaine.endsswith(suffixe) : res vaudra True si la chaine se termine par
le suffixe, False sinon.
prefixe et suffixe sont des chaînes de caratères.
102 Chapitre 8. Chaînes de caractères

 Exemple 8.4 — illustration des méthodes de test sur les chaînes. La séquence d’instructions

chaine = "hello"
print('La chaine "hello" :')
test_deb = chaine.startswith("hel")
print("débute par hel ?", test_deb)
test_fin = chaine.endswith("mo")
print("finie par mo ?", test_fin)

produit l’affichage suivant :


La chaine "hello" :
débute par hel ? True
finie par mo ? False

Définition 8.3.2 — méthodes de comptage. Les méthodes suivantes renvoient un nombre


entier :
— n = chaine.count(motif) : renvoie le nombre d’occurrences n de la chaîne motif
présentes dans la chaine.
— i = chaine.find(motif) : renvoie l’indice i du caractère où débute la première occur-
rence de la chaîne motif dans chaine ; renvoie -1 si la chaîne motif n’est pas trouvée.

 Exemple 8.5 — illustration des méthodes de comptage. La séquence d’instructions suivante :

chaine = "hello"
nbrel = chaine.count('l')
print("nbre de l=", nbrel)
nbrell = chaine.count('ll')
print("nbre de ll=", nbrell)
il = chaine.find('l')
print("indice du 1er l=", il)
iO = chaine.find('O')
print("indice du 1er O=", iO)

produit l’affichage suivant :


nbre de l= 2
nbre de ll= 1
indice du 1er l= 2
indice du 1er O= -1


Définition 8.3.3 — méthodes renvoyant des chaînes de caractères.


— majus = chaine.upper() : renvoie la chaîne majus, copie de chaine dont tous les
caractères alphabétiques sont transformés en majuscules (majuscule = uppercase).
— minus = chaine.lower() : renvoie la chaîne minus, copie de chaine dont tous les
caractères alphabétiques sont transformés en minuscules (minuscule = lowercase).
8.4 Parcours de chaînes de caractères 103

— liste = chaine.split(sep) : renvoie une liste dont les éléments sont des chaînes
obtenues en coupant la chaine suivant le séparateur sep.
— fusion = motif.join(liste) : renvoie la chaîne fusion dans laquelle tous les éle-
ments de liste sont concaténés en les séparant par la chaîne motif. La liste ne doit
comporter que des éléments de type str.
— res = chaine.replace(old, new) : renvoie la chaîne res, copie de chaine dans
laquelle toutes les occurrences de la chaîne old sont remplacées par la chaîne new.
 Exemple 8.6 — illustration des méthodes renvoyant des chaînes. La séquence d’instructions

chaine = "pain"
res1 = chaine.replace('n', 'x')
print("res1=", res1)
res2 = res1.replace('a', 'o')
print("res2=", res2)

chaine = "QwertY"
majus = chaine.upper()
print("majus=", majus)
minus = chaine.lower()
print("minus=", minus)

ip = "192.168.0.1"
liste = ip.split('.')
print("liste=", liste)
fusion = '-'.join(liste)
print("fusion=", fusion)

produit l’affichage suivant :


res1= paix
res2= poix
majus= QWERTY
minus= qwerty
liste= ['192', '168', '0', '1']
fusion= 192-168-0-1


8.4 Parcours de chaînes de caractères


8.4.1 Parcours itératif avec une boucle for
Les chaines de caractères sont des séquences itérables. Lorsque tous les caractères doivent être
parcourus, deux syntaxes de parcours sont possibles.
Définition 8.4.1 — Parcours d’une chaîne par le biais des indices. La structure de boucle
suivante permet d’itérer sur tous les indices d’une chaîne de caractères chaine :
104 Chapitre 8. Chaînes de caractères

for i in range(0, len(chaine)):


# instructions manipulant chaine[i]
# ...
# suite du programme

Définition 8.4.2 — Parcours d’une chaîne par le biais des caractères. La structure de
boucle suivante permet d’itérer sur tous les caractères d’une chaîne de caractères chaine :

for car in chaine:


# instructions manipulant le caractère carac
# ...
# suite du programme

À chaque itération, car prend pour valeur un des caractères de la chaine (du 1erau dernier) et
exécute les instructions.

è Les instructions contenues dans les boucles des définitions précédentes ne peuvent pas
modifier la chaîne de caractère, puisque les chaînes de caractères sont non mutables.

 Exemple 8.7 — parcours de chaînes. Pour une même chaîne de caractères chaine =

"bonjour", les boucles suivantes affichent les caractères de la chaîne séparés par des '*' :
1. Parcours par indices

for i in range(len(chaine)):
print(chaine[i] + "*", end="")
print(" fin")

2. Parcours par éléments

for car in chaine:


print(car + "*", end="")
print(" fin")

Les deux parcours sont équivalents, et produisent l’affichage suivant :


b*o*n*j*o*u*r* fin

8.4.2 Parcours itératif avec une boucle while


Lorsqu’on souhaite parcourir une partie des caractères de la chaîne, par exemple tous les
caractères tant qu’une condition est vérifiée, on utilise une boucle while.
Définition 8.4.3 — Parcours d’une partie des caractères d’une chaîne. Parcours d’une
chaîne tant qu’une condition_booléenne est vérifiée :
8.5 Construction itérative d’une chaîne 105

i = 0 # Compteur d’indice
while i < len(chaine) and condition_boolenne:
# instruction portant sur chaine[i]
# ...
i = i + 1 # Incrémentation de l’indice
# suite_du_programme

La condition_booéenne doit être précédée d’un test s’assurant qu’on ne dépasse pas le dernier
caractère de la chaîne.
 Exemple 8.8 — indice de la première occurrence de 'j'. Pour une même chaîne acquise

avec l’instruction chaine = input("un mot :") :

Variante 1. i = 0
while i < len(chaine) and chaine[i] != "j":
i = i + 1
if i == len(chaine):
print("'j' ne fait pas partie de " + chaine)
else:
print("'j' est à l'indice " + str(i))

Variante 2. if "j" not in chaine:


print("'j' ne fait pas partie de " + chaine)
else:
i = 0
while chaine[i] != "j":
i = i + 1
print("'j' est à l'indice " + str(i))

Les deux variantes produisent le même résultat et affichent :


'j' est à l'indice 3

lorsque l’utilisateur saisit "bonjour" 

8.5 Construction itérative d’une chaîne


Une chaîne de caractères n’étant pas mutable, lorsqu’on souhaite construire une chaîne sur la
base d’une autre, une solution est de la construire itérativement en partant d’une chaîne vide et en
concaténant au fur et à mesure les caractères qu’elle doit contenir.
 Exemple 8.9 — construction par accumulation. Le programme

chaine = "Le président : 06.01.02.03.04"


res = ""
for car in chaine:
if car in "0123456789":
res = res + "*"
else:
res = res + car
print(res)
106 Chapitre 8. Chaînes de caractères

produit l’affichage
Le président : **.**.**.**.**

8.6 Constantes du module string


Définition 8.6.1 — Constantes de module. Un module peut déclarer des constantes (par
exemple, la constante pi du module math). Ces constantes sont des variables utilisables en lec-
ture seulement. Après importation, elles sont accessibles avec la syntaxe nom_module.nom_constante.

Définition 8.6.2 — Constantes du module string. Le module string propose les constantes
suivantes :
— string.digits : la chaîne '0123456789'. ;
— string.ascii_lowercase : la chaîne contenant tous les caractères minuscules non
accentués : 'abcdefghijklmnopqrstuvwxyz'.
— string.ascii_uppercase : la chaîne contenant tous les caractères majuscules non
accentués : 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
— string.ascii_letters : la chaîne contenant tous les caractères non accentués, minus-
cules et majuscules.

Y Le module string propose d’autres constantes qui peuvent être utiles. Consultez la docu-
mentation officielle.

La table 8.1 donne des exemples d’utilisation de ces constantes.

Vérifier qu’un caractère est une lettre ? car in string.ascii_letters


Parcourir l’alphabet for car in string.ascii_lowercase
Connaître la position d’un caractère dans l’al- string.ascii_lowercase.find(car)
phabet
Tester si un caractère peut être transtypé en car in string.digits
int

TABLE 8.1 – Exemple d’utilisation des constantes du module string


9. Entrées-sorties sur des fichiers

9.1 Définitions
Définition 9.1.1 — Fichiers. Un fichier est un objet du système d’exploitation servant à stocker
de façon permanente des données.
Les fichiers peuvent être organisés en :
fichiers texte stockent des données sous forme de lignes successives. Les lignes (enregistre-
ments) sont séparées les unes des autres par une caractère de fin de ligne ('\n').
fichiers binaires ne présentent pas d’organisation apparente. Ce sont des données brutes, sous
forme numérique. Un fichier binaire est a priori illisible sans le programme conçu pour
l’exploiter (exemple : wav, mp3. . . ).

Les fichiers texte optent souvent pour une structuration tombant dans l’une des catégories
suivantes :
1. Structure avec délimitation. On rencontre beaucoup ce type de structuration dans les fichiers
de configuration système, sous Linux en particulier.
Harvey;Keitel;Mr White
Tim;Roth;Mr Orange
Michael;Madsen;Mr Blonde
Steve;Buscemi;Mr Pink

Le délimiteur est un caractère spécial (';', ':', '\t',. . . ) présent entre deux champs d’un
enregistrement (une ligne).
2. Structure à champs de largeur fixe.
Harvey Keitel Mr White
Tim Roth Mr Orange
MichaelMadsen Mr Blonde
Steve BuscemiMr Pink
Ce type de fichier occupe généralement plus d’espace mais est plus rapide d’accès.
108 Chapitre 9. Entrées-sorties sur des fichiers

9.2 Principes d’accès aux fichiers


L’accès à un fichier peut se comparer à l’accès à un livre ou un cahier :
1. Il faut l’ouvrir et place un pointeur d’accès (doigt) sur la première donnée écrite.
2. Il faut accéder à (lire) ses données, soit :
— en lisant les lignes caractère par caractère ; on parle alors d’accès séquentiel, où l’on
accède à la donnée suivante qu’après avoir lu la donnée courante en décalant à chaque
lecture le pointeur d’accès.
— en se déplaçant à la bonne page ; on parle d’accès direct, où l’on peut accéder directe-
ment à une donnée stockée en déplaçant le pointeur d’accès à l’endroit voulu.
3. Il faut fermer le livre à la fin.
Définition 9.2.1 — EOF : End Of File. Si un accès atteint la fin du fichier, le système d’exploita-
tion renvoie une condition « End Of File » (EOF) indiquant qu’aucune donnée supplémentaire
ne peut être lue sur cette source de données.

9.3 Ouverture et fermeture d’un fichier texte


L’ouverture d’un fichier se base sur la fonction fd = open(fichier, mode). Le paramètre
fichier est de type str et désigne le chemin d’accès au fichier dans le système d’exploitation. Le
paramètre mode est le mode d’accès (voir la table 9.1). La fonction open renvoie un descripteur de
fichier, de la classe file, qui contient notamment le pointeur d’accès au fichier.

Mode Signification
'r' lecture
'w' écriture avec création du fichier ou écrasement s’il existait
'a' ajout en fin de fichier

TABLE 9.1 – Modes d’accès lors de l’ouverture d’un fichier

La fermeture de fichier se fait à l’aide de la méthode fd.close(), où fd est le descripteur du


fichier.
L’encodage des caractères lus dans un fichier peut être précisé lors de l’ouverture en utilisant un
paramètre nommé encoding. Par exemple : fd = open('spam.txt', 'r', encoding='utf-8').
L’encodage spécifié doit bien entendu être conforme à celui utilisé lors de l’écriture du fichier. La
table 9.2 liste les encodages les plus fréquents.

Valeur de encoding Encodage


'UTF-8', 'UTF8', 'utf_8', 'U8', UTF8
'utf8'. . .
'latin_1', 'iso-8859-15', ASCII étendu Europe de l’ouest
'iso8859-15' '8859', 'cp819', 'latin',
'latin1'. . .
'cp1252', 'windows-1252' Microsoft Windows Europe de l’ouest
'utf_16_le', 'UTF-16LE' UTF16 little endian
'utf_16_be', 'UTF-16BE' UTF16 big endian

TABLE 9.2 – Encodages des caractères les plus fréquents

 Exemple 9.1 — Ouverture et fermeture d’un fichier existant. Pour un fichier cr.txt dans
situé dans le même répertoire que le script Python :
9.4 Gestionnaire de contexte 109

fd = open('cr.txt', 'r') # ouverture du fichier en lecture


# instructions utilisant le descripteur de fichier fd
# ...
fd.close() # fermeture

Y Si on tente d’ouvrir un fichier inexistant, cela provoque une erreur de type


IOError: [Errno 2] No such file or directory.

Y Fichiers binaires  Les fichiers binaires fonctionnent de façon similaire, il suffit
d’ajouter le caractère 'b' à la chaîne de caractère décrivant le mode.

9.4 Gestionnaire de contexte


Python propose une construction appelée gestionnaire de contexte (context manager) permettant
de gérer l’ouverture et la fermeture d’un fichier dans un bloc d’instructions. Sa syntaxe est la
suivante :

with open(fichier, mode, encoding='utf8') as fd:


# instructions utilisant fd
# ...
# fin du bloc with
# suite du programme

L’accès au fichier n’est possible que dans ce bloc. Le fichier est automatiquement fermé lors de la
sortie du bloc.

Y Cette syntaxe, ainsi que a spécification explicite de l’encodage des caractères, est très
fortement recommandée.

9.4.1 Lecture de fichiers texte


Si on considère un fichier décrit par un descripteur fd, sa lecture s’effectue à partir de la
position courante du pointeur d’accès au fichier à l’aide des méthodes suivantes :
— chaine = fd.read() renvoie la chaîne de caractères obtenue par la lecture du fichier en
totalité ;
— chaine = fd.read(nbre) renvoie la chaîne de caractères obtenue par la lecture de nbre
octets ;
— chaine = fd.readline() renvoie la chaîne de caractères obtenue après la lecture d’une
ligne du fichier (tous les caractères jusqu’au premier '\n' inclus).
À chaque lecture, le pointeur d’accès se déplace automatiquement pour viser les données qui
suivent celles lues.
Lorsque la fin de fichier est atteinte, la chaîne renvoyée par les méthodes de lecture est vide.
 Exemple 9.2 — affichage de chaque ligne d’un fichier précédée de son numéro. On lit
le fichier ligne à ligne :
110 Chapitre 9. Entrées-sorties sur des fichiers

with open("exemple.txt", 'r') as fd: # Ouverture en lecture


ligne = fd.readline() # Lecture de la 1ère ligne
no = 1
while ligne != '': # Tant que EOF n'est pas atteint
ligne = ligne.rstrip('\n') # Suppression du '\n' final
print(no, ':', ligne) # Affichage
ligne = fd.readline() # Lecture de la ligne suivante
no += 1

L’affichage produit par ce code, en considérant le fichier exemple précédent, est :


1 : Harvey;Keitel;Mr White
2 : Tim;Roth;Mr Orange
3 : Michael;Madsen;Mr Blonde
4 : Steve;Buscemi;Mr Pink

 Exemple 9.3 — même exemple : variantes.


1. lecture de l’ensemble des lignes dans une liste :

with open("exemple.txt", 'r') as fd: # Ouverture en lecture


lignes = fd.readlines() # Lecture des lignes
for no in range(len(lignes)):
ligne = lignes[no].rstrip('\n') # ligne avec suppression du \n
print(no+1, ':', ligne) # Affichage

2. lecture l’ensemble du fichier dans une seule chaîne :

with open("exemple.txt", 'r') as fd: # Ouverture en lecture


content = fd.read() # Lecture du fichier
lignes = content.rstrip('\n').split('\n') # Liste des lignes
for no in range(len(lignes)) :
ligne = lignes[no]
print(no+1, ':', ligne) # Affichage

9.4.2 Écriture dans un fichier texte


Si on considère un fichier décrit par son descripteur fd, la méthode fd.write(chaine) écrit la
chaîne passée en argument dans le fichier à la position pointée par le pointeur d’accès. Le pointeur
d’accès est automatiquement déplacé après les données écrites.
 Exemple 9.4 — concaténation de deux fichiers dans un troisième. Le programme suivant :

with open("fusion.txt", 'w') as fd_fusion:


with open("fichier1.txt", 'r') as fd1:
contenu = fd1.read() # Lecture du fichier1
fd_fusion.write(contenu) # Ecriture dans fusion

with open("fichier2.txt", 'r') as fd2:


fd_fusion.write(fd2.read()) # Lecture et écriture du 2eme fichier
9.4 Gestionnaire de contexte 111

donne, si fichier1.txt contient 'le␣fichier1' et fichier2.txt contient 'le␣fichier2',


un fichier fusion.txt contenant 'le␣fichier1le␣fichier2'. 

9.4.3 Positionnement du pointeur d’accès


Si on considère un fichier décrit par son descripteur fd :
— p = fd.tell() : renvoie la position courante p du pointeur d’accès sous la forme du nombre
d’octets séparant le pointeur du début du fichier.
— fd.seek(decalage, 0) : positionne le pointeur d’accès en le décalant de decalage octets
par rapport au début du fichier.
 Exemple 9.5 — positionnement. Le programme

fd = open("exemple.txt", 'r')
p = fd.tell()
print("p=", p, "car=", fd.read(1))
fd.seek(10, 0)
p = fd.tell()
print("p=", p, "car=", fd.read(1))
fd.seek(15, 0)
p = fd.tell()
print("p=", p, "car=", fd.read(1))
fd.close()

avec exemple.txt :
Harvey;Keitel;Mr White
Tim;Roth;Mr Orange
Michael;Madsen;Mr Blonde
Steve;Buscemi;Mr Pink

produit l’affichage suivant :


p= 0 car= H
p= 10 car= t
p= 15 car= r

Vous aimerez peut-être aussi