Vous êtes sur la page 1sur 41

~1~

Chapitre 4 : Les conteneurs à accès séquentiel


(Tuples, listes et chaines)
4.1. Introduction
Python permet de regrouper un ensemble de données de même type ou de types différents à
l’intérieur de structures de données spéciales appelées conteneurs. Il existe deux catégories de
conteneur :
- Les conteneurs séquentiels : On note les listes, les tuples et les chaines de caractères.
A l’intérieur de ces structures de données, les éléments sont rangés en utilisant des
index (commençant de 0).
- Les conteneurs à accès directs qui seront abordés dans le chapitre suivant.
Dans la suite, on va exposer les propriétés communes aux conteneurs séquentiels, puis on
abordera le côté spécifique de chacun de ces derniers.

4.2. Propriétés communes aux conteneurs :


Hypothèses : On dispose d’un conteneur C qui peut être :

 Une liste : Une séquence d’éléments encadrés par des crochets []

 Une chaine : une séquence de caractères encadrés par des côtes ou des chevrons ‘’ ou
«»:

 Un tuples : une séquence d’éléments encadrés par des parenthèses

Les opérations communes sur un conteneur séquentiel sont :

 Taille : len(C)

 Accès à un élément : C[index de l’élement] : Les index permis sont compris entre 0 et
len(C )-1 pour un parcours de gauche à droite et entre -1 et –len(C) pour un parcours
de droite à gauche
 Accès à une partie des éléments : C[i :j] : renvoie un conteneur constitué des éléments
se trouvant entre la position i et la position j-1.
NB :
- C[ :i] : renvoie la sous liste constituée des éléments d’indices compris entre 0 et i-1
- C[i :] : renvoie la sous liste constituée des éléments d’indices compris entre i et len(C)-
1.
- C[ ::] :renvoie la totalité de la liste

- C[ ::-1] : inverse la liste des éléments

 Accès à une partie des éléments avec notion de pas : C[i :j :k] : renvoie un conteneur
stockant les éléments entre les deux positions i et j-1 en effectuant des sauts
d’amplitude k

 Test d’appartenance : x in C

 Test de non appartenance : x not in C

 Concaténation : l’opérateur + permet de coller les éléments de deux ou plusieurs


conteneurs
 Répétition : C*n : l’opérateur * permet de créer un conteneur contenant n copies de C

 Recherche de la position d’un élément : C.index(x)

 Calcul du nombre d’occurrence d’un élément : C.count(x)

 Minimum et maximum : min(C), max(C)

Application :
- Créer un tuple t=(1,2,4,-6) et une chaine ch=’abc cd ! ;:’
- Appliquer toutes les commandes vues précédemment pour t et ch.
NB : Les conteneurs ne peuvent pas être tous modifiés après leurs créations, seules les listes
sont des structures de données modifiables ou mutables ou non immuables, tuples et chaines
sont non mutables ou immuables.

4.3. Commandes spécifiques aux listes


 création :
 liste vide :

 commande list :

 avec les [] :

 liste en compréhension : La syntaxe est la suivante : [expression for indice in


conteneur/itérable if condition] :
Application : retrouver les listes en compréhension présentées en haut en utilisant les boucles.
 par conversion

 modification : on utilise l’opérateur d’affectation =


 d’un élément

 d’un slice

Application : créer une liste contenant les entiers compris entre 0 et 5 puis modifier tous les
éléments impairs par des 0 en utilisant la notion de pas.

 ajout
 d’un élément à la fin : on utilise la commande append

 d’un slice : avec la commande extend

 insertion : avec la commande insert


 suppression
 d’un élément : trois possibilités : del, remove et pop

 d’un slice

 copie :
 copie normale : avec la commande copy :

 copie profonde : avec la commande deepcopy


 tri : avec la commande sort

 inversion : avec la commande reverse

4.4. Commandes spécifiques aux tuples :


 création :
 tuples vides :

 création directe avec les () :

 avec la commande tuple :

 par conversion

 en compréhension

 modification :
Les tuples sont non modifiables, toute tentative de mise à jour déclenche une erreur :
 ajout d’un élément :

 On écrase l’ancien tuples avec le résultat de la concaténation de t avec le tuple (1,)


 (1,) est un tuples composé d’un seul élément, la virgule est obligatoire.

4.5. Commandes spécifiques aux chaines :


 test de la nature de la chaine : alphabétique(isalpha), numérique(isidigit) ,
vide(isspace) ou alphanumérique(isalnum) :

 conversion majuscule / minuscule : upper et lower :

 commence avec/ se termine avec : startswith, endswith :

 éliminer les espaces à droite et à gauche : avec la commande strip :

 décomposition : commande split : décompose une chaine en utilisant un caractère


ou une sous chaine comme séparateur. Le résultat est toujours une liste :
 coller plusieurs chaines : commande join : opération réciproque de split :

 Recherche d’une sous chaine dans une autre chaine : commande find :

 Remplacer une sous chaine par une autre : commande replace :

 Affichage formaté : commande format : Syntaxe : chaine.format(parametres) :


Chapitre 5 : Les conteneurs à accès direct
(Dictionnaires & ensembles)
5.1. Introduction
Dans le chapitre précédent, on a traité les conteneurs séquentiels de Python. Pour accéder à un
élément d’un conteneur, on utilise son index. Les valeurs autorisées des index sont
obligatoirement séquentielles. Python permet d’utiliser une autre catégorie de conteneurs
maniant des index organisés d’une manière non séquentielle. Le conteneur n’est plus une
structure ordonnée, il s’agit bien d’un conteneur à accès direct.

5.2. Les dictionnaires


Un dictionnaire est un conteneur modifiable non ordonné composé d’une ensemble de couples
index : valeur. Les index sont aussi appelés des clés et les valeurs des entrées. La création
d’un dictionnaire peut se faire de plusieurs manières :

 Dictionnaire vide :

 La commande dict (avec comme paramètre une liste de listes, chacun de la forme
[clé ,valeur]) :

 Les {} :

 En compréhension
 Directement (en utilisant la syntaxe NomDict[cle]=valeur) :

La taille d’un dictionnaire qui est le nombre d’entrées qu’il contient est accessible via la
commande len, pour afficher une valeur correspondante à une clé, on utilise la syntaxe
NomDict[clé], les deux opérateurs in et not in testent l’appartenance d’une clé à un
dictionnaire :

Python permet d’accéder aux informations stockées au niveau d’un dictionnaire de plusieurs
manières :
Une entrée peut être accédée par la commande get :

Par contre, la commande setdefault permet de :

 créer une entrée vide si on fournit un index non encore utilisé et pas de valeur en
deuxième paramètre :

 Ajouter une entrée :

 Récupérer la valeur d’une clé existante :

La mise à jour d’un dictionnaire passe par l’ajout, la modification et la suppression d’entrées :

Python offre un ensemble de commande de mise à jour pour les dictionnaires :

 update : La syntaxe est d1.update(d2) : Fusionne deux dictionnaires. Si la clé figure


dans les deux dictionnaires alors la valeur de l’entrée correspondante dans d1 sera
mise à jour, sinon, une nouvelle entrée est créée dans d1 :
 pop : la syntaxe est NomDict.pop(index) : supprime l’entrée dont la clé est index et la
retourne en résultat ; popitem : la syntaxe est NomDict.popitem() : supprime
aléatoirement une entrée et la retourne :

 clear : La syntaxe est NomDict.clear() : efface le contenu d’un dictionnaire

 copy : La syntaxe est d2=d1.copy() : copie un dictionnaire dans un autre après avoir
importer le module copy.

5.3. Les ensembles


Les ensembles Python modélisent les ensembles mathématiques. C’est une collection d’objets
non ordonnées sans redondance de même types ou de types différents. Les éléments d’un
ensemble ne doivent jamais être des listes, des dictionnaires ou d’autres ensembles.
Un ensemble peut être créé de plusieurs manières :

 ensemble vide :

 la commande set :
 les {}

 en compréhension

Un ensemble est une structure de données non ordonnée. La commande len donne la
cardinalité de l’ensemble. On peut tester l’appartenance d’un élément à un ensemble mais on
ne peut pas utiliser un indice :

La mise à jour d’un ensemble est possible vue que c’est un type mutable :

 ajout d’un élément

 Suppression d’un élément :


 remove : La syntaxe est s.remove(elt) : supprime un élément existant et déclenche une
exception dans le cas échéant :
 discard : La syntaxe est s.discard(elt) : supprime un élément s’il existe et ne déclenche
pas d’erreurs si elt ne fait pas part de s :

 pop : Le syntaxe est s.pop() : supprimé un élément aléatoire de s et déclenche une


exception si l’ensemble est vide :

Toutes les opérations ensemblistes sont possibles en Python, on peut teste si :

 deux ensembles sont identiques ou différents : Les opérateurs de comparaisons ==


et != :

 deux ensembles sont disjoints (aucun élément en commun) :

 un ensemble est un sous ensemble d’un autre


 un ensemble contient un autre ensemble

 L’union

 L’intersection

 La différence

 La différence symétrique

Les opérations de réunion, intersection, différence et différence symétrique se présentent sous


une 2ème forme en python qui autorise une sorte de mise à jour de l’ensemble en question :
Chapitre 6 : Programmer des fonctions sous Python
6.1. Introduction
Python offre une panoplie de fonctions prédéfinies prêtes à l’utilisation. On distingue
les fonctions qui se chargent au moment du démarrage de l’interpréteur comme la
fonction abs() ou la fonction len() …(il suffit d’appeler ses fonctions en précisant le(s)
paramètre(s) de chacune), d’autres qui se chargent au moment de l’importation de
modules (cas de sqrt du module math ou de polar du module cmath) … Ce chapitre a
pour but d’initier à la programmation des fonctions en Python.

6.2. Définition
Une fonction est un bloc d’instructions qui possède un nom, qui reçoit un certain
nombre de paramètres et renvoie un résultat. L’usage des fonctions permet :
 d’éviter la répétition
 de séparer les données des résultats
 de rendre le code réutilisable à travers l’importation de fichiers de fonctions…
 et de décomposer les tâches complexes en tâches simples plus abordables.

On doit définir une fonction alors à chaque fois qu’un bloc d’instructions se trouve
répété à plusieurs reprises. Il s’agit d’une factorisation du code.

6.3. Syntaxe
Une fonction Python à la syntaxe suivante :

 Le mot clé def sert à déclarer un objet de type fonction


 Il est suivi du nom de la fonction ainsi que de parenthèses contenant les paramètres
de cette dernière (Si la fonction a plusieurs paramètres, on utilise les virgules pour
les séparer ; en cas ou il n’y a pas de paramètres, on ouvre et on ferme les
parenthèses obligatoirement ; on précise jamais le type des paramètres ; une
fonction peut recevoir des paramètres de natures différentes entre deux jeux
d’appels grâce à la notion de typage dynamique=le type d’une variable dépend de
son contenu)
 La chaine de documentation est optionnelle mais fortement recommandée.
 Le bloc d’instruction est obligatoire. L’instruction pass permet d’avoir un bloc
d’instruction vide (si on n’a pas encore désigné de quoi est chargé notre fonction).
6.4. Première fonction Python

On vient de créer une première fonction sous Python (La saisie peut être effectuée au
niveau du shell ou à l’intérieur d’une nouveau fichier .py, la différence entre les deux
cas sera traitée ultérieurement, mais pour le moment on opte pour la première option).
La fonction TableMul5 ne possède pas de paramètres, on lui a confié la responsabilité
d’afficher la table de multiplication de 5, ce qui explique la documentation entre triple
côtes… Une fois déclarée, la fonction peut être appelée comme le montre l’exemple
suivant :

Une fonction est définie pour assurer la factorisation du code et la réutilisabilité. Dans
l’exemple précédent, en dehors de la valeur 5, la fonction n’accepte aucune autre
valeur. D’où la pertinence de la notion de paramétrage. On redéfinit alors TableMul en
réservant un paramètre n qui représentera la valeur de l’entier dont on cherche à
afficher sa table de multiplication :

La fonction TableMul autorise des appels avec des paramètres de natures différentes
(Besoin de contrôle d’eventuelles erreurs de saisie à travers la gestion des
exceptions…)
:
6.5. Le NonType & les fonctions avec retour

On peut aller un peu plus loin avec les fonctions Python et développer une vraie
fonction qui retourne un résultat récupérable par la fonction appelante (on traitera plus
tard la fonction main qui représente la notion de programme principale). Le mot clé
return permet d’arrêter l’exécution d’une fonction et de renvoyer un résultat. Tous les
types vus en Python peuvent être utilisés comme un retour. Quand la fonction ne
programme pas d’instructions de type return, Python retourne tout de même un objet
vide ayant comme type NoneType. C’est un type réservé par le langage pour exprimer
le vide, tel est le cas d’une liste ou d’un tuple vide.

On va partir d’une fonction qui affiche la somme de deux entiers passés en paramètres :

En vérifiant le type du résultat obtenu, on tombe sur le cas d’un objet vide, très logique
print ne fait pas le travail de return :

Rectifions la fonction som de sorte qu’elle soit une vraie fonction avec un return :

Le type du résultat est bel et bien un entier. Le mot clé return peut figurer dans
plusieurs endroits au sein d’une fonction. La fonction signe retourne une chaine
exprimant le signe d’un argument x :
Quand une fonction programme plus d’un paramètre en retour, le type tuple s’avère
très utile. La fonction somdifprod calcule la somme, la différence et le produit de deux
entiers a et b passés en paramètres, un objet de type tuple constitué des trois résultats
est alors retourné. Au moment de l’appel, il faut prendre en considération la nature du
résultat. Soit qu’on utilise un objet qui stockera tout le tuple puis pour accéder aux
résultats on utilise les indices respectifs suivant la taille de ce dernier, soit qu’on
effectue un appel basé sur trois variables :

6.6. Mode de passage des paramètres


L’appel est une substitution (replacement) des paramètres formels par des paramètres
effectifs. Python différencie les données des résultats selon le type du paramètre :
 Les types non mutables (int, float, str, complex, bool, tuple…) sont passés par
valeur.
 Les types mutables (listes, ensembles, dictionnaires …) imitent le mode de passage
par variable (S et ES en algorithmique).

- Passage par valeur :

La première version de la fonction permut est supposée échanger le contenu des deux
variables a et b :
Sauf que le contenu des deux variables reste inchangé preuve que les types non
mutables ne peuvent pas être modifiés. Dans cette deuxième version, on effectue un
affichage du contenu de a et b à l’intérieur de la fonction avant la fin de son exécution

On constate que la modification n’est visible qu’à l’intérieur de la fonction. Les


paramètres ont un comportement local (Pour python, paramètres passés par valeur et
variables locales sont traitées de la même manière).
Pour réussir la permutation, l’appel doit écraser l’ancien contenu de a et de b en
utilisant une affectation :

- Passage par variable : Les objets mutables sont modifiables par nature. La fonction
ajout ajoute à la fin d’une liste l un objet x.
Pour mieux assimiler la notion de mode de passage, on se base sur l’évolution de la
valeur des identifiants des paramètres avant l’appel, au cours et à la fin de l’exécution
d’une fonction :

La variable x contient initialement la valeur 1. Python crée un identifiant sur la valeur


1 qui n’est autre que 17622d44272. En appelant la fonction, la valeur de l’identifiant
reste inchangée jusqu’à l’exécution de l’incrémentation. Python alors stocke dans x un
nouvel identifiant. C’est logique, x continent l’identifiant de 2 et plus celui de 1. Sauf
que ce changement n’est pas communiqué à l’extérieur de la fonction. L’affichage de
la valeur de x et de son identifiant après l’appel donne les valeurs initiales de l’avant
appel.

Vérifions les identifiants de la liste l avant, pendant et après l’exécution de ajout :

L’identifiant de la liste l est constant. La modification de l est visible à l’extérieur de la


fonction ajout. C’est le cas de tous les types mutables.
6.7. Paramètres avec valeur par défaut - Paramètres positionnels
Une fonction peut être déclarée avec des paramètres ayant une valeur des valeurs de
départ. Si l’utilisateur omet l’un des paramètres au moment de l’appel, la valeur par
défaut sera prise en considération tel est le cas de la fonction construire_point qui
affiche le point (0,0) si l’utilisateur ne communique aucun paramètre.

6.8. Paramètres positionnels


En plus de donner des valeurs de départ aux paramètres, python autorise d’appeler la
fonction sans trop respecter l’ordre des arguments au moment de la déclaration. Il
suffit d’utiliser le nom du paramètre au moment de l’appel et de préciser la valeur
qu’il prend :

6.9. Nombre de paramètres variable


Python permet de définir une fonction avec un nombre arbitraire de paramètres.
Généralement ce paramètre est appelé args ou params et il est toujours précédé du
caractère *. Utiliser ce modèle de fonctions permet une flexibilité de programmation
quand on ne sait pas vraiment quel sera le nombre de paramètres au moment de
l’appel. L’appel de la fonction est basé sur un tuple de valeurs :
6.10. Les fonctions imbriquées
Il est possible de déclarer une fonction g à l’intérieur d’une fonction f. Seule la
fonction f est capable d’appeler g. Cette dernière a un comportement local au sein de f.
Python offre deux commandes qui permettent de retourner une liste composée chacune
des noms des objets considérés comme locaux à une fonction et de leurs équivalent
globaux : locals() et globals() :

Suite à l’appel de la fonction min3, on obtient la liste des objets locaux et globaux
pour chacune des fonctions min2 et min3. La fonction min2 figure comme un objet
local à la fonction min3.
6.11. Les variables globales
Pour forcer une fonction à considérer une variable comme globale, on utilise le mot
clé global suivi du nom de la variable en question. La fonction inc1 utilise la variable
x sans la déclarer ni comme paramètre ni comme variable globale. L’interpréteur ne
reconnait pas x et déclenche une exception :

la deuxième version, inc2(), la variable x est déclarée globale d’une manière explicite.
La variable est initialisée à l’extérieur de la fonction et son contenu est modifiable par
les fonctions qui la déclarent comme avec le mot clé « global ».
6.12. Les fonctions lambda
En Python, une fonction lambda est une fonction anonyme (à laquelle on n’a pas
donné de nom), et qu’on peut appliquer “à la volée” dans une expression. La syntaxe
est : lambda paramètres : expression

NB : lambda est mot réservé du langage.

Les fonctions lambda sont réservées à des situations relativement simples. Leur
définition doit tenir sur une seule ligne, et elles ne peuvent pas contenir d’instructions
composées (pas d’affectation, pas de boucle, etc.). Elles consistent donc
essentiellement en la définition d’une expression calculée en fonction des paramètres
qui lui sont passés.

Pour prendre un exemple simpliste (et pas très utile), les deux définitions suivantes de
la fonction f sont équivalentes :

Les fonctions anonymes permettent d’appliquer deux commandes intéressantes sur les
listes :
 map : Applique une fonction sur tous les éléments d’une liste pour former une
nouvelle liste distincte de l’initiale. La syntaxe de map est la suivante :
list(map(f,l))

Supposons qu’on veut ajouter 1 à tous les éléments d’une liste l :

 filter : crée une liste contenant les éléments qui ne vérifient pas un critère spécifié
par une fonction f d’une liste initiale. La syntaxe de filter est la suivante :
list(filter(f,l))

Supposons qu’on veut supprimer tous les multiples de 3 d’une liste d’entiers :
6.13. Gestion des exceptions
Quand une erreur se produit dans un script, elle provoque l’arrêt du programme et
l’affichage d’un message d’erreur. Pour éviter cette interruption brutale, on peut
appliquer un traitement spécifique. Plus généralement, on peut traiter une situation
exceptionnelle dont on ne sait pas forcément où et quand elle va survenir à l’intérieur
d’un bloc donné. Plutôt que de parler d’erreur, on emploiera donc le terme “exception”
et prévoir une réaction adaptée à une exception, c’est la “rattraper”.

Pour le traitement des exceptions, Python offre la clause try: ... else.La forme la plus
simple est la suivante, où le bloc2 est parcouru si une exception (quelle qu’elle soit)
est rencontrée dans le bloc1 (cette exception provoque l’arrêt du bloc1 et le passage
immédiat au bloc2) :

On peut également prévoir un traitement particulier pour telle ou telle exception. Dans
ce cas, on utilisera une construction un peu plus élaborée, du genre :

On peut appliquer un même traitement à plusieurs exceptions. Pour celà, on écrira :


except (err1, err2, . . .) La construction except peut être complétée par une clause else,
exécutée si aucune exception n’a été levée/rattrapée. Python possède beaucoup
d’exceptions prédéfinies (cf http://docs.python.org/3.3/library/exceptions.html) En
voici juste quelques-unes :

 IndexError : Accès à un élément non existant d’une liste


 NameError : Utilisation d’un objet non existant
 SyntaxError : Erreur de syntaxe dans une instruction
 TypeError : Erreur de type
 ValueError : Erreur de valeur
 ZeroDivisionError : Division par 0
La gestion des exceptions favorise le contrôle des données. Au moment de la saisie,
l’utilisateur peut se tromper sur une valeur introduite. La fonction saisie par exemple
doit allouer la saisie de nouveau d’une nouvelle valeur en cas d’erreur en spécifiant la
nature du bug détecté avec un message explicatif :

6.14. Les modules personnels


Python permet de créer des modules personnels qui regroupent un ensemble de
fonctions et de variables (voir de classes, notion qui sera vue en deuxième année) à
l’intérieur d’un même fichier .py et de les utiliser en cas besoin. Le fichier possède un
nom défini par le programmeur. Avant de penser développer un module, vérifier que
python n’offre pas déjà une alternative.

 L’instruction import nom_module permet de charger la totalité du module en


mémoire. Les fonctions et les variables du module sont accessibles de la façon
suivante : nom_module.nom_element_du_module.
 Pour choisir les éléments à charger d’un module et gagner en mémoire, la syntaxe
suivante est sollicitée : from nom_module import fonction1,fonction2,var1 … Dans
ce cas, les éléments importés sont accessibles sans le prefixé nom_module.
 Le contenu d’un module est affiché par la commande dir(nom_module)
 L’aide est fournie par la commande help(nom_module)
Le regroupement de plusieurs modules dans un dossier donne naissance à un
paquetage (package en anglais).

On souhaite développer un module intitulé pile qui permet de créer une nouvelle
structure de donnée LIFO (Last In First Out). Cette structure repose sur deux
opérations :

 Empiler : ajouter un nouvel élément à la fin de la pile si cette dernière n’est pas
saturée
 Dépiler : supprimer toujours l’élément récemment ajouté si la pile n’est pas vide.

Sous Python, on ouvre un nouveau script avec CTRL+N, pour éditer notre script :
On enregistre ce script sous le nom de « pile.py ». Le module est prêt à l’utilisation :

En algorithmique, on appelle les fonctions et les procédures déjà déclarées au niveau


de l’algorithme principal ce qui est à l’encontre de Python, qui n’offre pas une
fonction principale comme en C ou en java (la fonction main()). Pour choisir les
instructions qui seront exécutées comme programme principal dans un script, on
utilise une variable spéciale name . Cette variable est créée par python partout et
renseigne, comme son nom l’indique sur le nom de tout objet utilisé (script, fonction,
variable…). Le shell est une fonction python qui porte le nom ‘ main ’. Ainsi, pour
forcer des fonctions à s’exéctuer comme programme principal, on teste si la variable
name contient la valeur ‘ main ’.

Le script suivant propose la saisie et le tri d’une liste :


L’appel du script précédent donne :

Vous aimerez peut-être aussi