Programmer en Python

Introduction

Cet article permet de télécharger Python et donne un grand nombre d'exemples de programmes permettant de démarrer rapidement avec ce langage de programmation.

Sommaire de cette page :

Télécharger Python


Documentation en PDF pour EduPython


Les différents types de variables


La structure conditionnelle if


Les boucles for et while


Formatage des chaînes de caractères


Lecture et écriture dans un fichier texte


Manipulation des listes en Python


Le module itertools


Exemples de programmes

Retour au sommaire

Télécharger Python

Voici deux distributions Python à installer sous Windows :

Python 3.4 avec l'interface de développement IDLE

EduPython 1.3

 

Retour au sommaire

 

Documentation en PDF pour EduPython

Les documents suivants permette de démarrer rapidement avec EduPython 1.3 :

Les bases

Les chaînes de caractères

Les nouveautés d'EduPython 1.3

La tortue

Statistiques et probabilités

Documentation complète d'EduPython 1.3

 

Retour au sommaire

 

Les différents types de variables

En python les types principaux sont :

Voici un aperçu rapide de la syntaxe et de l'utilisation de base de ces différents types de données.

Les types numériques

Les nombres se classe en trois catégories de base :

Voici les 7 opérateurs applicables sur les nombres entiers :

L'addition :

>>> 89+7
96

La soustraction :

>>> 89-7
82

La multiplication :

>>> 89*7
623

La division décimale (le résultat est un réel) :

>>> 89/7
12.714285714285714

La division entière (le résultat est un entier) :

>>> 89//7
12

Le reste de la division entière (opérateur modulo) :

>>> 89%7
5

La puissance :

>>> 89**7
44231334895529

En Python les nombres entiers peuvent avoir une taille arbitraire. Exemples :

>>> 857**23
28744774383296734139436728971609899947735788428826430686679055946793
>>> 2597**654
1160526488716095895589360900081157070776877494104312366288161828848098533208602268554329517
4417122241203763175617871708570716570081185023211056354441490949160522254078438002811600371
2075255952170936657736581427117388836252640549853609297388243327387329044383993117592697257
3863047724755521623637842890613526309797523617121425662860313403556478475627816252851426567
4555083778323248127443403483260542943453343380879064126560500904504276493774171788502921576
2015304397165596403307303268978563328770786838265060387656532224360090972495610363886209973
1054703544671172004068735485920556271455389234927767098615538363099113304862211905748619072
9317788196303795477305800618573199501241889218135515809136047505378784773661169374892597340
3541968826936612257503425480532090434870231754589147468239857413210824299881508804156280809
8820330025582213906566997065096501973689857705956604027428328701272444900783862520864579311
6228182313068441598593998036215589439911225582126864185056938864471543134488063593195689447
9353726030878814271756143181399568546874561896824128720789790642103622223138211091711892297
8839289963410285867397432774702879362234262744276578288684901352108754656342288458255972924
4285787236235938629970853459783746742947056143958958499366922742067408990675515213525424845
7435593704636005401953451143499457571013295300161464523386117400669616360353395193119695815
3442073697734779172639715147315432380898996564477021523150909883170219311374473483473426481
3424524085057575327659411708142221636580113487498514616772964147997566229990499605757622488
9296854238832350793473570145052350457182791398981529824056546084139359763174104023936137981
7372299432755866783227360700614751526172005879796840846742972002701675108028309134596093269
2533617827007774958802079256842610047551342676809460459257624309728619465668215108487667498
7267557809567301503811529416415525821131692876323101848712155581717340007687988867592241680
8721559991124337805496024375136049699927364168804206816212445650806904652976818511168593675
7029569745761108759951536344789611293417713923869528796312002012866194500944339663392376838
8367573185632068341634476811546685957105417548327804701065278969509696118875468127544288724
24131828053257612680142756893626582832783131468969

Les nombres à virgule flottante, utilisant le point comme séparateur décimal, utilisent les 7 opérateurs précédents et peuvent être écrits en écriture scientifique avec l'opérateur e symbolisant une puissance de 10 :

>>> 23.56+89.7
113.26
>>> 1e3
1000.0
>>> 78e-4
0.0078
>>> 56.89**45
9.475824738100925e+78
>>> 4.5**7.3
58674.763877464145
>>> 79.4//7
11.0
>>> 79.4%7
2.4000000000000057

Les nombres complexes s'écrivent avec l'opérateur j (et sans opérateur entre la partie imaginaire et j) :

>>> 2+3j
(2+3j)
>>> 7.8-9.4j
(7.8-9.4j)
>>> (8-2j)*(6+9j)
(66+60j)
>>> (4.5-7.8j)/(10.3+9.63j)
(-0.1446685533999675-0.6220234787143993j)

La fonction complex permet de créer un objet nombre complexe possédant certaines méthodes :

>>> z=complex(2,3)
>>> z
(2+3j)

Partie réelle :

>>> z.real
2.0

Partie imaginaire :

>>> z.imag
3.0

Complexe conjugué :

>>> z.conjugate()
(2-3j)

La fonction valeur absolue (abs) permet de calculer le module du nombre complexe :

>>> abs(z)
3.6055512754639896

La fonction puissance (pow) permet d'élever un nombre complexe à une certaine puissance :

>>> pow(z,3)
(-46+9j)

Exemple d'application : pour calculer la racine carrée d'un nombre complexe on l'élève à la puissance 1/2 :

>>> z=complex(7,3)
>>> pow(z,0.5)
(2.703310295347531+0.5548752588933428j)
>>> _**2
(7.000000000000001+3.0000000000000004j)

Remarque : le symbole _ représente le résultat de l'opération précédente

Le module cmath de Python permet d'obtenir l'argument (phase) ou la forme polaire (module et argument) d'un nombre complexe :

>>> from cmath import *
>>> z=complex(4,3)
>>> phase(z)
0.6435011087932844
>>> polar(z)
(5.0, 0.6435011087932844)

Le module cmath de Python contient également des fonctions avancées sur les nombres complexes comme par exemple les fonctions trigonométriques.

D'autres types numériques plus évolués et non vus ici existent aussi en Python en utilisant des modules spécifiques (rationnels, décimaux, fractions, vecteurs, matrices, etc.).

 

Les chaînes de caractères

Les chaînes de caractères peuvent être encadrées par 4 délimitateurs différents :

Exemples :

>>> "Bonjour"
'Bonjour'
>>> "Ceci est une chaîne contenant des 'simples quotes' dans ces caractères"
"Ceci est une chaîne contenant des 'simples quotes' dans ces caractères"
>>> 'Ceci est une chaîne contenant des "doubles quotes" dans ces caractères'
'Ceci est une chaîne contenant des "doubles quotes" dans ces caractères'
>>> """Ceci est une chaîne
... de caractères contenant
... des retours à la ligne"""
'Ceci est une chaîne\nde caractères contenant\ndes retours à la ligne'
>>> """Voici une chaîne contenant à la fois des 'simples' et des "doubles" quotes"""
'Voici une chaîne contenant à la fois des \'simples\' et des "doubles" quotes'

>>> '''Voici une chaîne de caratères contenant à la fois des 'simples quotes' et des "doubls quotes"'''
'Voici une chaîne de caratères contenant à la fois des \'simples quotes\' et des "doubls quotes"'

L'accès direct à un caractère se fait en l'indexant à partir de 0 :

>>> s="Python"
>>> s[0]
'P'
>>> s[1]
'y'
>>> s[2]
't'

Un index négatif part de la fin de la chaîne (s[-1] étant le dernier caractère) :

>>> s[-1]
'n'
>>> s[-2]
'o'
>>> s[-3]
'h'

Il est possible de définir une "tranche" de la chaîne en utilisant le caractère deux points.

Les caractères du début au 3 (non compris) :

>>> s[:3]
'Pyt'

Les caractères du 3 (compris) à la fin de la chaîne :

>>> s[3:]
'hon'

Les caractères 1 (compris) à 4 (non compris) :

>>> s[1:4]
'yth'

Les caractères 0 (compris) à 5 (non compris) par pas de 2 (un sur 2) :

>>> s[0:5:2]
'Pto'

La concaténation de deux chaînes de caractères se fait avec l'opréteur + :

>>> "Ceci "+"est une chaîne"+" de caractères"
'Ceci est une chaîne de caractères'
>>> s1="Voici un"
>>> s2=" message composé "
>>> s3="de 3 chaînes"
>>> print(s1,s2,s3)
Voici un message composé de 3 chaînes
>>> print(s1+s2+s3)
Voici un message composé de 3 chaînes

Voici quelques méthodes ou fonctions pratiques apppliquées sur une chaîne de caractères :

>>> s="Python permet de manipuler facilement les chaînes de caractères"
>>> s.count('m')
3
>>> s.count('de')
2
>>> len(s)
63
>>> s.index('p')
7
>>> s.replace(' ','_')
'Python_permet_de_manipuler_facilement_les_chaînes_de_caractères'
>>> s
'Python permet de manipuler facilement les chaînes de caractères'
>>> s.split(' ')
['Python',
'permet',
'de',
'manipuler',
'facilement',
'les',
'chaînes',
'de',
'caractères']

D'autres méthodes avancées non vues ici sont applicables à un objet chaîne de caractères.

 

Les listes

Les listes se notent entre crochets :

>>> [1,2,3,4]
[1, 2, 3, 4]

La concaténation de deux listes se fait avec l'opréteur + :

>>> [1,2,3]+[4,5,6]
[1, 2, 3, 4, 5, 6]

Comme pour les chaînes de caractères, l'accès à un élément de la liste de fait par indexation à partir de zéro :

>>> l=[1,2,3,4,5,6]
>>> l[0]
1
>>> l[1]
2
>>> l[5]
6

Un index négatif permet de partir de la fin de la liste (l[-1] étant le dernier élément de la liste) :

>>> l=[1,2,3,4,5,6]
>>> l[-1]
6
>>> l[-2]
5
>>> l[-5]
2
>>> l[-6]
1

Comme pour les chaînes de caractères un système de tranchage utilisant le caractère deux points permet d'extraire facilement une partie de la liste :

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

L'opérateur in permet de tester si un élément est présent dans la liste :

>>> 3 in [1,2,3,4]
True
>>> 5 in [1,2,3,4]
False

La fonction list convertit une chaîne de caractères (ou tout autre objet composé) en liste :

>>> list("bonjour")
['b', 'o', 'n', 'j', 'o', 'u', 'r']
>>> list({1,2,3,4})
[1, 2, 3, 4]
>>> list((1,2,3,4))
[1, 2, 3, 4]

La fonction range permet de créer rapidement des listes d'entiers :

>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(1,20))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> list(range(14,31))
[14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
>>> list(range(3,40,2))
[3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39]
>>> list(range(3,40,3))
[3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39]
>>> list(range(3,40,4))
[3, 7, 11, 15, 19, 23, 27, 31, 35, 39]

 

Les ensembles

Les ensembles se notent entre accolades :

>>> {1,2,3,4}
{1, 2, 3, 4}

Ils ne peuvent pas contenir de doublons :

>>> {1,2,3,2,4}
{1, 2, 3, 4}

Retire un élément à un ensemble :

>>> {1,2,3,4,5}-{3}
{1, 2, 4, 5}

Union de deux ensembles :

>>> {1,2,3}|{3,4,5}
{1, 2, 3, 4, 5}

Intersection de deux ensembles :

>>> {1,2,3}&{3,4,5}
{3}

"Ou-exclusif" entre deux ensembles (équivaut à l'union moins l'intersection) :

>>> {1,2,3}^{3,4,5}
{1, 2, 4, 5}
>>> ({1,2,3}|{3,4,5})-({1,2,3}&{3,4,5})
{1, 2, 4, 5}

Conversion d'un ensemble en liste :

>>> list({1,2,3,4})
[1, 2, 3, 4]

Conversion d'une liste en ensemble :

>>> set([1,2,3,4])
{1, 2, 3, 4}

Supression des doublons dans une liste :

>>> list(set([1,2,1,3,4,2,3,1,4,1,2,3,4]))
[1, 2, 3, 4]

 

Les dictionnaires

Tout comme les listes, les dictionnaires sont des objets composés et modifiables, mais l'accès à un élément se fait ici par clé et non par position.

Création d'un dictionnaire vide :

>>> dico={}
>>> dico
{}

Ajout de la valeur "dupont" avec la clé "nom" :

>>> dico["nom"]="dupont"
>>> dico
{'nom': 'dupont'}

Ajout d'autres éléments dans le dictionaire :

>>> dico["prénom"]="pierre"
>>> dico
{'nom': 'dupont', 'prénom': 'pierre'}
>>> dico["age"]=23
>>> dico
{'age': 23, 'nom': 'dupont', 'prénom': 'pierre'}

Affichage des éléments du dictionnaire :

>>> print(dico["prénom"],dico["nom"],"a",dico["age"],"ans.")
pierre dupont a 23 ans.

Création directe d'un dictionnaire contenant 3 éléments :

>>> dico={'nom':'durand','prenom':'paul','age':18}
>>> dico
{'age': 18, 'nom': 'durand', 'prenom': 'paul'}

La méthode keys() permet d'obtenir l'ensemble des clés du dictionnaire :

>>> dico.keys()
dict_keys(['nom', 'age', 'prenom'])
>>> list(dico.keys())
['nom', 'age', 'prenom']

La méthode values() permet d'obtenir l'ensemble des valeurs du dictionnaire :

>>> dico.values()
dict_values(['durand', 18, 'paul'])
>>> list(dico.values())
['durand', 18, 'paul']

L'opérateur in permet de tester si une clé est présente dans le dictionnaire :

>>> 'nom' in dico
True
>>> 'age' in dico
True
>>> 'adresse' in dico
False
>>> 'paul' in dico
False

La méthode items() renvoie les paires clé/valeur sous forme de tuples :

>>> dico.items()
dict_items([('nom', 'durand'), ('age', 18), ('prenom', 'paul')])
>>> list(dico.items())
[('nom', 'durand'), ('age', 18), ('prenom', 'paul')]

La méthode clear() vide le dictionaire :

>>> dico.clear()
>>> dico
{}

Appliquée à un dictionnaire, la fonction list renvoie la liste des clés :

>>> list({'a': 1, 'b': 2, 'c': 3})
['a', 'c', 'b']

Et voici 4 solutions différentes pour créer le même dictionnaire contenant 3 éléments en utilisant le constructeur dict() ou la fonction zip() :

>>> dico={'a':1,'b':2,'c':3}
>>> dico
{'a': 1, 'b': 2, 'c': 3}
>>> dico.clear()
>>> dico
{}
>>> dico=dict(a=1,b=2,c=3)
>>> dico
{'a': 1, 'b': 2, 'c': 3}
>>> dico.clear()
>>> dico
{}
>>> dico=dict([['a',1],['b',2],['c',3]])
>>> dico
{'a': 1, 'b': 2, 'c': 3}
>>> dico.clear()
>>> dico
{}
>>> dico=dict(zip('abc',[1,2,3]))
>>> dico
{'a': 1, 'b': 2, 'c': 3}

 

Retour au sommaire

 

La structure conditionnelle if

Voici rapidement les différentes syntaxes de la structure conditionnelle if en Python.

Un test simple :

>>> m=12
>>> if m==12:
...    print("La variable m vaut douze")
...
La variable m vaut douze
>>>

Un test complet :

>>> m=12
>>> if m!=12:
...    print("La variable m ne vaut pas douze")
... else:
...    print("La variable m vaut douze")
...
La variable m vaut douze

Un test avec des conditions logiques :

>>> m=12
>>> if (m % 2==0) and (m>9):
...    print("m est pair et supérieur à 9")
...
m est pair et supérieur à 9

Condition logique avec un ET (noté and) et un OU (noté or) :

>>> m=-7
>>> if (m % 2==0) and (m>9) or (m<0):
...    print("m est pair et supérieur à 9, ou bien m est négatif")
...
m est pair et supérieur à 9, ou bien m est négatif

L'opérateur logique not permet de tester une condition complémentaire :

>>> m=15
>>> if not((m % 2==0) and (m>9)):
...    print("m n'est pas un nombre pair supérieur à 9")
...
m n'est pas un nombre pair supérieur à 9

Plusieurs tests imbriqués avec le mot clé elif :

>>> m=53
>>> if m>100:
...    print("m est supérieur à 100")
... elif m<10:
...    print("m est inféreur à 10")
... else:
...    print("m est compris entre 10 et 100")
...
m est compris entre 10 et 100

En utilisant à la fois les opérateurs logiques and, or et not dans les formulations des conditions logiques complexes et les tests complets et imbriqués avec if, elif et else il est possible de tester finement toutes situations afin d'en détecter tous les cas particuliers recherchés.

Retour au sommaire

 

Les boucles for et while

La boucle for s'applique à un objet composé, et bouclera tant que l'objet contient encore des éléments à extraire.

Boucle for sur une chaîne de caractère :

>>> for i in "bonjour":
...    print(i)
...
b
o
n
j
o
u
r

Boucle for sur une liste :

>>> for i in [1,2,3,4]:
...    print(i)
...
1
2
3
4

Boucle for sur un ensemble :

>>> for i in {1,2,3,4}:
...    print(i)
...
1
2
3
4

Boucle for sur un dictionnaire (la boucle parcourt seulement les clés du dictionnaire) :

>>> for i in {'a':1,'b':2,'c':3,'d':4}:
...    print(i)
...
a
c
b
d

Affichage des entiers de 0 à 8 dans une boucle for grâce à la fonction range :

>>> for i in range(9):
...    print(i)
...
0
1
2
3
4
5
6
7
8

Affichage des entiers de 1 à 9 dans une boucle for grâce à la fonction range :

>>> for i in range(9):
...    print(i+1)
...
1
2
3
4
5
6
7
8
9

La boucle for peut être complétée d'un bloc else exécuté seulement à la fin de la boucle :

>>> for i in range(1,10):
...    print(i)
... else:
...    print("fin")
...
1
2
3
4
5
6
7
8
9
fin

Un break permet de sortir de force de la boucle sans aller jusqu'à la fin des valeurs initialement prévues dans la liste énumérée :

>>> for i in range(1,10):
...    print(i)
...    if i==4:
...       break
...
1
2
3
4

En cas de sortie de force par break le bloc situé après else n'est pas exécuté :

>>> for i in range(1,10):
...    print(i)
...    if i==4:
...       break
... else:
...    print("fin")
...
1
2
3
4

La boucle while boucle tant qu'une condition logique est vraie. On sort de la boucle lorsque la condition sera fausse.

>>> n=0
>>> while n<8:
...    print(n)
...    n=n+1
...
0
1
2
3
4
5
6
7

Grâce aux opérateurs logiques and, or et not la condition logique peut être d'une complexité quelconque :

>>> n=0
>>> while not(n>100 or n<60 and n>10 and not(n%3!=0)):
...    print(n)
...    n=n+1
...
0
1
2
3
4
5
6
7
8
9
10
11

Le mot clé break permet de sortir de force de la boucle :

>>> n=0
>>> while 1:
...    n=n+1
...    if n==18:
...       break
...
>>> print(n)
18

Remarque : while 1: ou while True: lance une boucle infinie dont la seule issue est le déclanchement conditionnel d'un break dans la boucle.

Par défaut la boucle while commence par tester sa condition avant de rentrer dans la boucle (si la condition est fausse dès le début on ne rentre jamais dans la boucle), alors qu'une boucle infinie avec un test à la fin sortant par break oblige à entrer au moins une fois dans la boucle (équivalent à une boucle "repeat until").

Tout comme la boucle for, la boucle while peut être complétée d'un bloc else exécuté une seule fois à la sortie de la boucle, c'est-a-dire lorsque la condition devient fausse :

>>> n=1
>>> while n<10:
...    print(n)
...    n+=1
... else:
...    print("fin")
...
1
2
3
4
5
6
7
8
9
fin

Remarque : n+=1 est strictement équivalent à n=n+1

En cas de sortie de force par break le bloc situé après else n'est pas exécuté (car la condition testée par la boucle while n'a jamais été fausse) :

>>> n=1
>>> while n<10:
...    print(n)
...    n+=1
...    if n==4:
...       break
... else:
...    print("fin")
...
1
2
3

Retour au sommaire

 

Formatage des chaînes de caractères

En Python, la fonction historique printf (ou sprintf) permettant le formatage des chaînes de caractères dans d'autres langages de programmation (langage C, Perl, PHP, etc.) n'existe pas.

Pour formater une chaîne de caractère en Python il existe 2 solutions :

Voici un apperçu rapide de ces deux solutions de mise en forme.

L'opérateur %

Dans la chaîne à formater (à gauche de %) les motifs %s sont remplacés par les différents éléments placés dans le tuple à droite de % :

>>> print("Ceci %s un premier %s illustrant le %s de chaîne avec l'opérateur %%" % ("est","exemple","formatage",))
Ceci est un premier exemple illustrant le formatage de chaîne avec l'opérateur %

Remarque : le motif %% affiche le caractère %

Il est également possible de mettre en forme des nombres, en plus des chaînes de caractères :

>>> print("Voici un entier : %d Voici une chaîne : %s Et voici un nombre réel : %f" % (5,"bonjour",4.79))
Voici un entier : 5 Voici une chaîne : bonjour Et voici un nombre réel : 4.790000

On remarque que par défaut le motif %f affiche 6 chiffres après la virgule. Pour afficher seulement 2 chiffres par exemple il faut utiliser le motif %.2f :

>>> print("Voici le même réel 100/7 dans différent formats : %f %.1f %.2f %.3f %.4f %d" % (100/7,100/7,100/7,100/7,100/7,100/7))
Voici le même réel 100/7 dans différents formats : 14.285714 14.3 14.29 14.286 14.2857 14

On remarque que %f arrondi par excès.

>>> print("Voici le même réel 17.9999 dans différent formats : %f %.2f %.1f %.0f %d" % (17.9999,17.9999,17.9999,17.9999,17.9999))
Voici le même réel 17.9999 dans différents formats : 17.999900 18.00 18.0 18 17

On remarque que %.0f affiche l'entier le plus proche alors que %d affiche la partie entière.

Remarque : l'opérateur * permet de multiplier un tuple à élément unique pour obtenir le même élément plusieurs fois à condition que le tuple finisse par une virgule :

>>> 7*(4,)
(4, 4, 4, 4, 4, 4, 4)

L'exemple précédent peut alors s'écrire en inscrivant une seule fois le nombre 17.9999 qui s'affichera 5 fois :

>>> print("Voici le même réel 17.9999 dans différent formats : %f %.2f %.1f %.0f %d" % (5*(17.9999,)))
Voici le même réel 17.9999 dans différent formats : 17.999900 18.00 18.0 18 17

Voici l'ensemble des motifs utilisables dans la chaîne à formater avec l'opérateur % :

Motif
Rôle
%s
convertit tout objet en chaîne de carctères
%c
caractère unicode
%d
entier en base 10 (décimal)
%i et %u
identique à %d mais obsolète
%o
entier en base 8 (octal)
%x et %X
entier en base 16 (hexadécimal)
%f et %F
nombre réel en affichage décimal
%e et %E
nombre réel en affichage scientifique
%g et %G
nombre réel en affichage automatique (entier, décimal ou scientifique)
%.3f %.3g et %.3e
utilisation d'une précision fixe (ici 3 chiffres)
%8.3f %8.3g et %8.3e
précision de 3 chiffres sur 8 caractères minimum
%*f %*g et %*e
utilisation d'une longueur variable (à préciser dans le tuple passé à %)
%.*f %.*g et %.*e
utilisation d'une précision variable (à préciser dans le tuple passé à %)
%*.*f %*.*g et %*.*e
utilisation d'une longueur et d'une précision variables
%%
affiche le caractère %

Voici quelques exemples illustrant la différence entre %f, %e et %g pour l'affichage des nombres réels :

>>> print("Voici le réel %f avec %%e : %e et avec %%g : %g" % (3*(17.9999,)))
Voici le réel 17.999900 avec %e : 1.799990e+01 et avec %g : 17.9999

>>> print("Voici le réel %f avec %%e : %e et avec %%g : %g" % (3*(0.0045,)))
Voici le réel 0.004500 avec %e : 4.500000e-03 et avec %g : 0.0045

>>> print("Voici le réel %f avec %%e : %e et avec %%g : %g" % (3*(500000,)))
Voici le réel 500000.000000 avec %e : 5.000000e+05 et avec %g : 500000

>>> print("Voici le réel %f avec %%e : %e et avec %%g : %g" % (3*(1e42,)))
Voici le réel 1000000000000000044885712678075916785549312.000000 avec %e : 1.000000e+42 et avec %g : 1e+42

>>> print("Voici le réel %f avec %%e : %e et avec %%g : %g" % (3*(23e-9,)))
Voici le réel 0.000000 avec %e : 2.300000e-08 et avec %g : 2.3e-08

>>> print("Voici le réel %f avec %%e : %e et avec %%g : %g" % (3*(8,)))
Voici le réel 8.000000 avec %e : 8.000000e+00 et avec %g : 8

>>> print("Voici le réel %f avec %%e : %e et avec %%g : %g" % (3*(100/7,)))
Voici le réel 14.285714 avec %e : 1.428571e+01 et avec %g : 14.2857

On remarque que %g affiche automatiquement le nombre :

Configurons une précisions de 3 chiffres pour chacun des motifs %f, %e et %g en écrivant %.3f, %.3e et %.3g :

>>> print("Voici le réel %.3f avec %%.3e : %.3e et avec %%.3g : %.3g" % (3*(100/7,)))
Voici le réel 14.286 avec %.3e : 1.429e+01 et avec %.3g : 14.3

On pourrait remarquer que :

Dans tous les cas avant de vouloir généraliser une règle à tous les nombres et toutes les situations, rien ne vaut une observation poussée sur différentes valeurs avec différents motifs en utilisant le mode intéractif dans la console de Python pour se faire une idée :

>>> print("%.3g %.3g %.3g %.3g %.3g %.3g" % (17.9999,0.0045,500000,23e-9,8,100/7))
18 0.0045 5e+05 2.3e-08 8 14.3
>>> print("%.5g %.5g %.5g %.5g %.5g %.5g" % (17.9999,0.0045,500000,23e-9,8,100/7))
18 0.0045 5e+05 2.3e-08 8 14.286

Il est possible d'indiquer la précision à utiliser dans une variable en utilisant le caractère * dans le motif de formatage. Exemples :

Affichage du réel 100/7 avec la précision par défaut :

>>> '%f' % (100/7)
'14.285714'

Affichage du réel 100/7 avec une précision fixe de 2 décimales :

>>> '%.2f' % (100/7)
'14.29'

Affichage du réel 100/7 avec une précision variable en utilisant le caractère * dans le motif de formatage avec la précision qui est indiquée dans le premier élément du tuple passé à l'opérateur % :

>>> '%.*f' % (2,100/7)
'14.29'

>>> '%.*f' % (3,100/7)
'14.286'

La précision est ici enregistrée dans la variable a :

>>> a=4;'%.*f' % (a,100/7)
'14.2857'

L'utilisation d'une précision variable est également possible avec les motifs de formatage %e et %g :

>>> '%.*e' % (3,100/7)
'1.429e+01'
>>> '%.*e' % (5,100/7)
'1.42857e+01'
>>> '%.*g' % (3,100/7)
'14.3'
>>> '%.*g' % (5,100/7)
'14.286'

Remarque : avec l'opérateur % la valeur de la précision variable doit être placée AVANT le réel à formater.

Configuration d'un nombre minimal de caractères dans le tuple passé à % (ici 15 caractères en tout) :

>>> '%*f' % (15,100/7)
'      14.285714'
>>> '%*e' % (15,100/7)
'   1.428571e+01'
>>> '%*g' % (15,100/7)
'        14.2857'

Longueur et précision variables (ici 3 chiffres affichés sur 10 caractètes en tout) :

>>> '%*.*f' % (10,3,100/7)
'    14.286'
>>> '%*.*e' % (10,3,100/7)
' 1.429e+01'
>>> '%*.*g' % (10,3,100/7)
'      14.3'

Exemple d'application : une fonction qui affiche toute valeur numérique avec 3 chiffres significatifs en utilisant le bon préfixe précédé d'une valeur entre 1 et 999 :

def prefixe(n):
    if n>=1e9:
        s="%.3g G" % (n/1e9)
    elif n>=1e6:
        s="%.3g M" % (n/1e6)
    elif n>=1e3:
        s="%.3g k" % (n/1e3)
    elif n<1e-9:
        s="%.3g p" % (n*1e12)
    elif n<1e-6:
        s="%.3g n" % (n*1e9)
    elif n<1e-3:
        s="%.3g µ" % (n*1e6)
    elif n<1:
        s="%.3g m" % (n*1e3)
    else:
        s="%.3g" % (n)
    return s

print(prefixe(14e10))
print(prefixe(0.123))
print(prefixe(0.0147))
print(prefixe(0.005698))
print(prefixe(0.000487589))
print(prefixe(1e-13))
print(prefixe(1e-12))
print(prefixe(1e-11))
print(prefixe(1e-10))
print(prefixe(1e-9))
print(prefixe(1e-8))
print(prefixe(1e-7))
print(prefixe(1e-6))
print(prefixe(1e-5))
print(prefixe(0.1))
print(prefixe(1))
print(prefixe(10))
print(prefixe(100))
print(prefixe(1000))
print(prefixe(10000))
print(prefixe(100000))
print(prefixe(1000000))
print(prefixe(456.7854874589))
print(prefixe(45.7854874589))
print(prefixe(4.7854874589))
print(prefixe(0.7854874589))
print(prefixe(0.07854874589))
print(prefixe(0.007854874589))

Et voici le résultat affiché :

140 G
123 m
14.7 m
5.7 m
488 µ
0.1 p
1 p
10 p
100 p
1 n
10 n
100 n
1 µ
10 µ
100 m
1
10
100
1 k
10 k
100 k
1 M
457
45.8
4.79
785 m
78.5 m
7.85 m

 

La méthode format appliquée à une chaîne de caractères

La méthode format permet d'aller plus loin que l'opérateur % (ou la fonction historique printf) pour la formatage des chaînes, notament dans les trois domaines suivants :

Voyons rapidement les possibilités de la méthode format dans ces trois domaines.

1 - le repérage des éléments

Dans la chaîne à formater les motifs de remplacement sont ici des paires d'accolades {}

Par défaut les éléments sont pris dans l'ordre du tuple passé en paramètre à format :

>>> print("Cette {} a été {} avec la {} format".format("chaîne","formatée","méthode"))
Cette chaîne a été formatée avec la méthode format

Il est possible de choisir l'élément à afficher en fonction de sa position (à partir de zéro) :

>>> print("Cette {2} a été {0} avec la {1} format".format("formatée","méthode","chaîne"))
Cette chaîne a été formatée avec la méthode format

Ceci permet d'utiliser plusieurs fois le même élément :

>>> print("Le {1} de la {0} à formater avec la méthode {1} est une {0} contenant des accolades".format("chaîne","format"))
Le format de la chaîne à formater avec la méthode format est une chaîne contenant des accolades

Il est possible de passer à la méthode format une liste, à condition de préfixer son nom par * :

>>> liste=["formatée","méthode","chaîne"]
>>> print("Cette {2} a été {0} avec la {1} format".format(*liste))
Cette chaîne a été formatée avec la méthode format

On peut également nomer les éléments afin de les repérer autrement que par leur position :

>>> print("Le {animal} qui est {lieu} est en train de {verbe} une {complément}".format(lieu="sur le balcon",complément="souris",verbe="manger",animal="chat"))
Le chat qui est sur le balcon est en train de manger une souris

Il est possible de passer à la méthode format un dictionnaire, à condition de préfixer son nom par ** :

>>> dico={"lieu":"sur le balcon","complément":"souris","verbe":"manger","animal":"chat"}
>>> print("Le {animal} qui est {lieu} est en train de {verbe} une {complément}".format(**dico))
Le chat qui est sur le balcon est en train de manger une souris

2 - l'alignement lors de l'affichage

La méthode format possède des possibilités avancées d'alignement du texte. Exemples :

Alignement à droite sur 12 caractères :

>>> '{:>12}'.format("Python")
'      Python'

Alignement à gauche sur 12 caractères :

>>> '{:<12}'.format("Python")
'Python      '

Alignement centré sur 12 caractères :

>>> '{:^12}'.format("Python")
'   Python   '

Par défaut le caractère de remplissage pour l'alignement est l'espace, mais il est possible d'imposer un caractère particulier :

>>> '{:x>12}'.format("Python")
'xxxxxxPython'
>>> '{:_<12}'.format("Python")
'Python______'
>>> '{:#^12}'.format("Python")
'###Python###'

 

3 - le formatage des nombres

Affichage d'un nombre entier avec {:d}

Le paramètre :d permet d'afficher un entier relatif dans la base décimale (système de numération à base 10) :

>>> '{:d}'.format(5)
'5'
>>> '{:d}'.format(-5)
'-5'

Affichage systématique du signe :

>>> '{:+d}'.format(5)
'+5'
>>> '{:+d}'.format(-5)
'-5'

Affichage du signe - ou d'un espace :

>>> '{: d}'.format(5)
' 5'
>>> '{: d}'.format(-5)
'-5'

Affichage d'un nombre entier dans différentes bases avec :b :o :x et :X

Affichage en binaire naturel (système de numération à base 2) avec {:b}

>>> '{:b}'.format(49)
'110001'

Préfixe l'affichage par 0b rappelant que le nombre est exprimé en base 2 :

>>> '{:#b}'.format(49)
'0b110001'

Affichage en binaire naturel sur 8 bits en complétant les poids forts par des 0 :

>>> '{:08b}'.format(49)
'00110001'

Affichage en octal (système de numération à base 8) avec {:o}

>>> '{:o}'.format(49)
'61'

Préfixe l'affichage par 0o rappelant que le nombre est exprimé en base 8 :

>>> '{:#o}'.format(49)
'0o61'

Affichage en hexadécimal (système de numération à base 16) avec {:x} et {:X}

>>> '{:x}'.format(10861)
'2a6d'
>>> '{:X}'.format(10861)
'2A6D'

Préfixe l'affichage par 0x ou 0X rappelant que le nombre est exprimé en base 16 :

>>> '{:#x}'.format(10861)
'0x2a6d'
>>> '{:#X}'.format(10861)
'0X2A6D'

Exemple d'application de l'affichage en base 2 : affichage d'un nombre en binaire réfléchi

Pour afficher le nombre x en binaire réfléchi il suffit de demander à Python d'afficher en binaire naturel le résultat du Ou-Exclusif bit à bit entre x et sont décalage à droite d'un rang en utilisant '{:b}'.format(x ^ (x>>1)) :

>>> x=54
>>> print("Le nombre {:d} s'écrit {:b} en binaire réfléchi".format(x,x ^ (x>>1)))
Le nombre 54 s'écrit 101101 en binaire réfléchi

Affichage d'un nombre à virgule flotante avec {:f}

Par défaut :f affiche 6 chiffres après la virgule :

>>> '{:f}'.format(100/7)
'14.285714'

Arrondit le nombre par excès avec 3 décimales :

>>> '{:.3f}'.format(100/7)
'14.286'

Affichage sur 8 caractères en tout avec 3 décimales :

>>> '{:8.3f}'.format(100/7)
'  14.286'

Affichage sur 15 caractères en tout :

>>> '{:15f}'.format(100/7)
'      14.285714'

On peut cumuler plusieurs formatages pour affiner l'affichage final. Par exemple :

>>> '{:_^+15.5f}'.format(100/7)
'___+14.28571___'

Affichage en écriture scientifique avec {:e} et {:E}

>>> '{:e}'.format(100/7)
'1.428571e+01'
>>> '{:e}'.format(0.0234)
'2.340000e-02'
>>> '{:e}'.format(1000)
'1.000000e+03'
>>> '{:E}'.format(0.00000056)
'5.600000E-07'

Affichage optimisé avec {:g} et {:G}

>>> '{:g}'.format(100/7)
'14.2857'
>>> '{:g}'.format(1000)
'1000'
>>> '{:g}'.format(0.56)
'0.56'
>>> '{:g}'.format(0.00000056)
'5.6e-07'
>>> '{:G}'.format(0.00000056)
'5.6E-07'

Utilisation d'une précision variable indiquée dans les paramètres de la fonction format :

>>> '{:.{}f}'.format(100/7,2)
'14.29'
>>> '{:.{}f}'.format(100/7,4)
'14.2857'

Affichage de 3 décimales sur un total de 8 caractères :

>>> '{:{}.{}f}'.format(100/7,8,3)
'  14.286'

Utilisation d'une variable pour indiquer la précision :

>>> precision=3;'{:.{}f}'.format(100/7,precision)
'14.286'

La variable precision peut être elle-même formatée avant son utilisation :

>>> precision=3.14;'{:.{:.0f}f}'.format(100/7,precision)
'14.286'

La précision variable marche aussi avec les motifs de formatage {:e} et {:g} :

>>> '{:.{}e}'.format(100/7,4)
'1.4286e+01'
>>> '{:.{}g}'.format(100/7,4)
'14.29'

Configuration d'un nombre minimal de caractères dans les paramètres de format :

>>> '{:{}f}'.format(100/7,15)
'      14.285714'
>>> '{:{}f}'.format(100/7,10)
' 14.285714'

Longueur et précision variables :

>>> '{:{}.{}e}'.format(100/7,15,4)
'     1.4286e+01'
>>> '{:{}.{}g}'.format(100/7,15,4)
'          14.29'

Remarque : avec la fonction format la valeur de la précision variable doit être placée APRES le réel à formater.

Récapitulatif de la syntaxe de format

Motif
Rôle
Choix des éléments
{}
prend les éléments dans l'ordre dans le tuple passé à format
{0} {1} {2}
choix d'un élément par sa position ou utilisation d'une liste
{nom} {verbe} {objet}
choix d'un élément par son nom ou utilisation d'un dictionnaire
Les nombres entiers
{:d}
entier en base 10 (décimal)
{:b}
entier en base 2 (binaire naturel)
{:o}
entier en base 8 (octal)
{:x} et {:X}
entier en base 16 (hexadécimal)
{:#b} {:#o} {:#x} {:#X}
préfixe le nombre par la base (0b 0o 0x ou 0X)
Les nombres décimaux
{:f}
nombre réel en affichage décimal
{:e} et {:E}
nombre réel en affichage scientifique
{:g} et {:G}
nombre réel en affichage automatique (entier, décimal ou scientifique)
{:8.3f} {:8.3e} {:8.3g}
précision de 3 décimales sur 8 caractères minimum
{:{}f} {:{}e} {:{}g}
utilisation d'un nombre de caractères variable
{:.{}f} {:.{}e} {:.{}g}
utilisation d'une précision variable
{:{}.{}f} {:{}.{}e} {:{}.{}g}
utilisation d'un nombre de caractères et d'une précision variables
{:+d} {: d} {:+f} {: f}
affichage du signe
L'alignement
{:<12}
alignement à gauche avec 12 caractères
{:>12}
alignement à droite avec 12 caractères
{:^12}
affichage centré avec 12 caractères
{:_<12} {:_>12} {:_^12}
choix du caractère de remplisage pour l'alignement

 

Retour au sommaire

 

Lecture et écriture dans un fichier texte

Pour accéder à un fichier on commence par créer un objet fichier grâce à la fonction open :

fic=open('toto.txt','w') : crée un nouveau fichier toto.txt

fic=open('toto.txt','a') : ouvre le fichier pour y ajouter des lignes

fic=open('toto.txt','r') : ouvre le fichier en lecture seule

Pour ajouter des chaînes de caractères dans le fichier on utilise la méthode write associé aux objets fichiers :

fic.write("bonjour")

Pour ajouter une nouvelle ligne il faut utiliser un \n dans la chaîne à écrire :

fic.write("ceci est une ligne\n")

Pour fermer le fichier après utilisation on utilise la méthode close :

fic.close()

Pour lire toutes les lignes d'un fichier ouvert en lecture on utilise l'objet fichier dans une boucle for :

for ligne in fic:
    print(ligne)

 

Exemple d'application : la sauvegarde et la restauration d'une liste de mots de passe dans un fichier :

liste_mot=["linux","python","soleil","maison"]

fic=open("mot_de_passe.txt",'w')
for mot in liste_mot:
    fic.write(mot+"\n")

fic.close()

liste=[]

fic=open("mot_de_passe.txt",'r')
for mot in fic:
    print(mot.strip())
    liste.append(mot.strip())

print(liste)

Remarque : mot.strip() enlève le retour à la ligne \n à la fin de la chaîne mot

 

Mais le plus simple pour générer rapidement un fichier texte est de rediriger la sortie standard vers un nouveau fichier texte ouvert en écriture :

import sys
sys.stdout=open('sortie.txt','w')

Ainsi, tout ce qu'écrira print sera envoyé vers le fichier sortie.txt.

 

Retour au sommaire

 

Manipulation des listes en Python

Un des points forts du langage Python est la création, la génération, l'analyse et la manipulation des listes. Voici la syntaxe de base et les méthodes natives liées aux listes en Python.

Créer une liste :

>>> liste=[1,2,'trois',"4"]

Une liste s'écrit entre crochets et peut contenir des objets de différents types.

Affichage brut d'une liste :

>>> print(liste)
[1, 2, 'trois', '4']

Affichage de tous les éléments d'une liste :

>>> for i in liste:
...    print(i)
...
1
2
trois
4

Ajoute un élément à la liste :

>>> liste.append(5)
>>> liste
[1, 2, 'trois', '4', 5]

Convertit la liste en ensemble, c'est-à-dire une collection d'objets sans doublon, mais sans notion d'ordre :

>>> set(liste)
{1, 2, 'trois', '4', 5}

A retenir :

En Python une liste est ordonnée et peut contenir des doublons. Au contraire, un ensemble ne peut pas contenir de doublon et ne contient pas d'ordre.

Exemple : on ajoute une nouvelle fois l'élément 2 à la liste :

>>> liste.append(2)
>>> liste
[1, 2, 'trois', '4', 5, 2]

L'ensemble issu de la liste ne contient qu'une seule fois l'élément 2 :

>>> set(liste)
{1, 2, 'trois', '4', 5}

Supprime les doublons dans la liste en passant par un ensemble :

>>> liste=list(set(liste))
>>> liste
[1, 2, 'trois', '4', 5]

Nombre d'éléments dans une liste :

>>> len(liste)
5

Accès aux éléments d'une liste :

Les indices commencent à 0. Par exemple pour une liste de 8 éléments les indices vont de 0 à 7 :

>>> liste=[1,2,3,4,5,6,7,8]
>>> liste[0]
1
>>> liste[1]
2
>>> liste[2]
3
>>> len(liste)
8
>>> liste[len(liste)-1]
8
>>> liste[7]
8

Le premier élément d'une liste se sélectionne par :

>>> liste[0]
[1]

Les indices négatifs ont un sens et commencent à la fin de la liste :

>>> liste=[1,2,3,4,5,6,7,8]
>>> liste[-1]
8
>>> liste[-2]
7
>>> liste[-3]
6
>>> liste[-4]
5
>>> liste[-7]
2
>>> liste[-8]
1

Le dernier élément d'une liste se sélectionne par :

>>> liste[-1]
[8]

Découpage d'une liste en tranches :

>>> liste=[1,2,3,4,5,6,7,8]
>>> liste[2:4]
[3, 4]
>>> liste[2:5]
[3, 4, 5]
>>> liste[2:]
[3, 4, 5, 6, 7, 8]
>>> liste[:3]
[1, 2, 3]
>>> liste[:5]
[1, 2, 3, 4, 5]
>>> liste[:]
[1, 2, 3, 4, 5, 6, 7, 8]

Extrait une tranche de liste (sous forme d'une liste) avec des indices négatifs :

>>> liste=[1,2,3,4,5,6,7,8]
>>> liste[-5:-2]
[4, 5, 6]
>>> liste[2:-3]
[3, 4, 5]
>>> liste[3:-1]
[4, 5, 6, 7]
>>> liste[-6:-5]
[3]
>>> liste[2:3]
[3]
>>> liste[2]
3

Avec 3 paramètres, la syntaxe d'extraction d'une tranche (avec les deux points) parmet de sélectionner un élément sur 2, ou sur 3, etc.

>>> liste[0:8]
[1, 2, 3, 4, 5, 6, 7, 8]
>>> liste[0:8:2]
[1, 3, 5, 7]
>>> liste[0:8:3]
[1, 4, 7]
>>> liste[1:8:2]
[2, 4, 6, 8]

Exemple d'application : extrait seulement les nombres pairs ou impairs d'une liste d'entiers ordonnée :

>>> list(range(20))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> list(range(20))[5]
5
>>> list(range(20))[0:20]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> list(range(20))[0:20:2]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> list(range(20))[1:20:2]
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

Avec un indice direct (positif ou négatif) le dépassement d'indice est interdit et provoque une erreur :

>>> liste=[1,2,3,4,5]
>>> liste[8]
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
IndexError: list index out of range
>>> liste[-7]
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
IndexError: list index out of range

Avec la syntaxe des tranches, le dépassement d'indice est autorisé et ne provoque pas d'erreur. Seul les éléments réels de la liste présents dans l'intervalle sont sélectionnés :

>>> liste=[1,2,3,4,5]
>>> liste[-7:8]
[1, 2, 3, 4, 5]
>>> liste[-2:36]
[4, 5]
>>> liste[19:36]
[]

Ordonne un ensemble ou une liste numérique sans modifier l'original :

>>> sorted({7,3,9,1,4})
[1, 3, 4, 7, 9]
>>> sorted([7,3,9,1,4])
[1, 3, 4, 7, 9]

La fonction sorted() renvoie une nouvelle liste sans modifier la liste originale :

>>> liste=[7,3,9,1,4]
>>> liste
[7, 3, 9, 1, 4]
>>> sorted(liste)
[1, 3, 4, 7, 9]
>>> liste
[7, 3, 9, 1, 4]

Modifie la position des éléments dans une liste afin de l'ordonner :

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

La méthode sort() liée aux listes modifie la liste originale.

La fonction range() permet de créer facilement des listes numériques :

>>> liste=range(10)
>>> liste
range(0, 10)
>>> list(liste)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Avec un seul paramètre range(n) crée une liste numérique contenant les entiers de 0 à n-1 (par pas de 1) :

>>> list(range(20))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

Avec 2 paramètres range(n,m) crée une liste numérique contenant les entiers de n à m-1 (par pas de 1) :

>>> list(range(20,29))
[20, 21, 22, 23, 24, 25, 26, 27, 28]

Avec 3 paramètres range(n,m,k) crée une liste numérique contenant les entiers de n à m-1 par pas de k :

>>> list(range(20,29,3))
[20, 23, 26]

L'opérateur + permet de concaténer plusieurs listes :

>>> liste1=[1,2,3]
>>> liste2=[4,5,6]
>>> liste1+liste2
[1, 2, 3, 4, 5, 6]

L'opérateur * permet de multiplier une liste :

>>> 3*liste1
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> 4*["oui","non"]
['oui', 'non', 'oui', 'non', 'oui', 'non', 'oui', 'non']

>>> 7*[4]
[4, 4, 4, 4, 4, 4, 4]
>>> 4*[1,2,3]
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]

Le mot clé in permet de vérifier si un élément appartient à une liste. Le résulat est booléen :

>>> liste=[1,2,3,4,5]
>>> 2 in liste
True
>>> 7 in liste
False

Pour tester si une liste contient des doublons ou pas il suffit de comparer le nombre d'éléments de la liste avec le nombre d'éléments de l'ensemble créé à partir de cette liste :

Cas d'une liste sans doublon :

>>> liste=[1,2,3,4,5]
>>> if len(liste)==len(set(liste)):
...     print("Cette liste ne contient pas de doublon")
... else:
...     print("Cette liste contient des doublons")
...
Cette liste ne contient pas de doublon

Cas d'une liste avec doublon :

>>> liste=[1,2,3,2,5]
>>> if len(liste)==len(set(liste)):
...     print("Cette liste ne contient pas de doublon")
... else:
...     print("Cette liste contient des doublons")
...
Cette liste contient des doublons

Pour copier une liste a dans une autre variable b l'affectation simple a=b réserve des surprises :

>>> a=[1,2,3,4,5]
>>> b=a
>>> a
[1, 2, 3, 4, 5]
>>> b
[1, 2, 3, 4, 5]
>>> b[2]=6
>>> a
[1, 2, 6, 4, 5]
>>> b
[1, 2, 6, 4, 5]

En fait a et b sont deux pointeurs pointant vers la même liste en mémoire.

Si on veut dupliquer physiquement tous les éléments de la liste a dans une nouvelle liste b il faut utiliser la syntaxe des tranches sélectionnant toute la liste :

>>> a=[1,2,3,4,5]
>>> b=a[:]
>>> a
[1, 2, 3, 4, 5]
>>> b
[1, 2, 3, 4, 5]
>>> b[2]=6
>>> a
[1, 2, 3, 4, 5]
>>> b
[1, 2, 6, 4, 5]

Python dispose d'une syntaxe simple permettant de filtrer une liste, c'est-à-dire de créer une nouvelle liste avec seulement les éléments de la liste d'origine répondant à un critère précis. Cette syntaxe permettant de décrire rapidement une liste s'appelle la compréhension de liste.

Exemple : la liste liste contient les entiers de 0 à 19 :

>>> liste=list(range(20))
>>> liste
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

On crée une nouvelle liste z à partir de la liste liste :

>>> z=[i for i in liste]
>>> z
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

z est pour l'instant identique à liste.

Mais dans la création de la liste z à partir des éléments de liste, on peut ajouter une condition de filtrage. Par exemple on ne sélectionne que les éléments de liste supérieur à 10 :

>>> z=[i for i in liste if i>10]
>>> z
[11, 12, 13, 14, 15, 16, 17, 18, 19]

Si on veut que z ne contiennent que les éléments pair de liste on écrira :

>>> z=[i for i in liste if i % 2 == 0]
>>> z
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

Et des opérateurs logiques permettent d'affiner la condition. Par exemple tous les entiers impairs inférieurs ou égal à 15 :

>>> z=[i for i in liste if i % 2 == 1 and i<=15]
>>> z
[1, 3, 5, 7, 9, 11, 13, 15]

Autre exemple : la liste z contient 5 fois les multiples de 3 inférieurs à 12 :

>>> z=[5*i for i in liste if i % 3 == 0 and i<=12]
>>> z
[0, 15, 30, 45, 60]

Exemple d'application du filtrage de liste : on crée une liste z contenant les 26 lettres de l'alphabet en majuscule :

>>> z=[chr(65+i) for i in range(26)]
>>> z
['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']

Autre exemple : on veut une liste z contenant 20 entiers aléatoires compris chacun entre 0 et 100 :

>>> import random
>>> z=[random.randint(0,100) for i in range(20)]
>>> z
[4, 74, 33, 2, 63, 74, 22, 57, 65, 38, 35, 86, 52, 40, 13, 17, 10, 65, 83, 3]
>>> len(z)
20

Le filtrage de liste ci-dessus permet d'écrire en une seule ligne la création manuelle de la liste z en utilisant la méthode append dans une bouble for :

>>> z=[]
>>> for i in range(20):
...    z.append(random.randint(0,100))
...
>>> z
[10, 40, 51, 51, 61, 78, 89, 13, 43, 5, 83, 14, 32, 45, 79, 24, 51, 65, 64, 27]
>>> len(z)
20

Mais les deux solutions précédentes ne garantissent pas l'absence de doublons (en rouge dans la liste z ci-dessus).

Si on veut une liste z contenant 20 entiers aléaroires tous différents il faut supprimer les doublons à chaque itération dans une boucle while :

>>> z=[]
>>> while len(z)<20:
...    z.append(random.randint(0,100))
...    z=list(set(z))
...
>>> z
[67, 4, 69, 38, 49, 43, 45, 46, 27, 17, 82, 52, 53, 36, 90, 91, 60, 37, 62, 31]
>>> len(z)
20

Pour sortir tous les éléments qui sont en communs dans deux listes il faut utiliser le filtrage avec un test d'appartenance in dans la condition de la compréhension de liste :

>>> a=[1,2,3,4,5,6,7,8,9]
>>> b=[3,10,6,12,18,4,16]
>>> [i for i in a if i in b]
[3, 4, 6]

Remarque : pour trouver les éléments communs à deux listes on peut aussi utiliser l'intersection (opérateur &) des ensembles créés à partir des listes :

>>> a=[1,2,3,4,5,6,7,8,9]
>>> b=[3,10,6,12,18,4,16]
>>> list(set(a) & set(b))
[3, 4, 6]

Recherche des éléments communs à 3 listes :

>>> a=[1,2,3,4,5,6,7,8,9]
>>> b=[3,10,6,12,18,4,16]
>>> c=[4,5,6,7]
>>> [i for i in a if i in b and i in c]
[4, 6]

Pour mélanger une liste il faut utiliser la fonction shuffle du module random :

>>> import random
>>> liste=list(range(10))
>>> liste
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> random.shuffle(liste)
>>> liste
[8, 1, 6, 5, 7, 0, 2, 4, 3, 9]
>>> random.shuffle(liste)
>>> liste
[6, 5, 8, 7, 9, 3, 2, 1, 4, 0]

Tous ces exemples de base utilisant la syntaxe native de Python et la compréhension de liste pour la manipulation des listes permettent désormais de réaliser facilement tous les traitements utiles sur les listes, et démontre l'avantage principal de Python dans ce domaine par rapport à d'autres langages de programmation.

 

Retour au sommaire

 

Le module itertools

Le module itertools de Python contient de nombreuses fonctions puissantes et bien pratiques pour la génération de combinaisons de listes complexes.

Pour utiliser le module itertools il faut commencer par l'importer :

>>> import itertools

La commande print(itertools.__doc__) nous donne ensuite la liste des 18 itérateurs du module itertools :

Les 3 itérateurs infinis :

count([n]) --> n, n+1, n+2, ...
cycle(p) --> p0, p1, ... plast, p0, p1, ...
repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times

Les 11 itérateurs de séquences, ou séquenceurs :

accumulate(p, start=0) --> p0, p0+p1, p0+p1+p2
chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...
compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...
dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails
groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)
filterfalse(pred, seq) --> elements of seq where pred(elem) is False
islice(seq, [start,] stop [, step]) --> elements from
       seq[start:stop:step]
starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...
tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n
takewhile(pred, seq) --> seq[0], seq[1], until pred fails
zip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...

Les 4 générateurs combinatoires :

product(p, q, ... [repeat=1]) --> cartesian product
permutations(p[, r])
combinations(p, r)
combinations_with_replacement(p, r)

Voyons comment utiliser ces itérateurs à travers des exemples concrets.

Les 3 itérateurs infinis

Itérateur : count(n)

Rôle : renvoie une liste infinie d'entiers naturels à partir de n (ou de 0 si utilisé sans paramètre)

Exemple :

Affichage de tous les entiers à partir de 0. La boucle for ne finit jamais :

for i in count():
  print(i)

Affichage des entiers de 5 à 21. On quitte la boucle for grâce à l'instruction break exécutée si i>20 (donc lorsque i=21) :

for i in count(5):
  print(i)
  if i>20:
    break

 

Itérateur : cycle(P)

Rôle : renvoie à tour de rôle et de manière cyclique tous les éléments du conteneur P

Exemple :

Si le conteneur P est une chaîne on obtient tous les caractères de manière cyclique :

cycle('ABCD') renvoie A B C D A B C D A B C D ... et répète le cycle A B C D à l'infinie

Si le conteneur P est une liste on obtient tous les éléments de manière cyclique :

cycle([1,2,3]) renvoie 1 2 3 1 2 3 1 2 3 etc. sans arrêt

 

Itérateur : repeat(x,n)

Rôle : renvoie n fois l'élément x (ou une infinité de fois avec un seul paramètre x)

Exemple :

repeat(8) renvoie 8 à chaque itération, et ce une infinité de fois

repeat(8,5) renvoie 8 à chaque itération pendant seulement 5 itérations

Affiche 7 fois la chaîne "Python" :

for i in repeat("Python",7):
   print(i)

Python
Python
Python
Python
Python
Python
Python

 

Les 11 séquenceurs :

Itérateur : accumulate()

Rôle : renvoie

Exemple :

 

Itérateur : chain()

Rôle : renvoie

Exemple :

 

Itérateur : compress()

Rôle : renvoie

Exemple :

 

Itérateur : dropwhile()

Rôle : renvoie

Exemple :

 

Itérateur : groupby()

Rôle : renvoie

Exemple :

 

Itérateur : filterfalse()

Rôle : renvoie

Exemple :

 

Itérateur : islice()

Rôle : renvoie

Exemple :

 

Itérateur : starmap()

Rôle : renvoie

Exemple :

 

Itérateur : tee()

Rôle : renvoie

Exemple :

 

Itérateur : takewhile()

Rôle : renvoie

Exemple :

 

Itérateur : zip_longest()

Rôle : renvoie

Exemple :

 

Les 4 générateurs combinatoires :

Itérateur : product(P,Q,...[repeat=n])

Rôle : renvoie toutes les listes à n éléments possibles en utilisant les conteneurs P, Q, etc.

Exemple :

Si n n'est pas précisé par le paramètre repeat, alors le nombre d'éléments dans les listes générées correspond au nombre de conteneurs :

>>> list(product([1,2,3],[4,5,6,7]))
[(1, 4),
(1, 5),
(1, 6),
(1, 7),
(2, 4),
(2, 5),
(2, 6),
(2, 7),
(3, 4),
(3, 5),
(3, 6),
(3, 7)]

On peut préciser la taille des listes voulues grâce au paramètre repeat :

>>> list(product([1,2,3],repeat=2))
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]

>>> list(product([1,2,3],repeat=3))
[(1, 1, 1),
(1, 1, 2),
(1, 1, 3),
(1, 2, 1),
(1, 2, 2),
(1, 2, 3),
(1, 3, 1),
(1, 3, 2),
(1, 3, 3),
(2, 1, 1),
(2, 1, 2),
(2, 1, 3),
(2, 2, 1),
(2, 2, 2),
(2, 2, 3),
(2, 3, 1),
(2, 3, 2),
(2, 3, 3),
(3, 1, 1),
(3, 1, 2),
(3, 1, 3),
(3, 2, 1),
(3, 2, 2),
(3, 2, 3),
(3, 3, 1),
(3, 3, 2),
(3, 3, 3)]

On peut passer autant de listes qu'on veut à product :

>>> list(product(range(4),range(4),range(4)))
[(0, 0, 0),
(0, 0, 1),
(0, 0, 2),
(0, 0, 3),
(0, 1, 0),
(0, 1, 1),
(0, 1, 2),
(0, 1, 3),
(0, 2, 0),
(0, 2, 1),
(0, 2, 2),
(0, 2, 3),
(0, 3, 0),
(0, 3, 1),
(0, 3, 2),
(0, 3, 3),
(1, 0, 0),
(1, 0, 1),
(1, 0, 2),
(1, 0, 3),
(1, 1, 0),
(1, 1, 1),
(1, 1, 2),
(1, 1, 3),
(1, 2, 0),
(1, 2, 1),
(1, 2, 2),
(1, 2, 3),
(1, 3, 0),
(1, 3, 1),
(1, 3, 2),
(1, 3, 3),
(2, 0, 0),
(2, 0, 1),
(2, 0, 2),
(2, 0, 3),
(2, 1, 0),
(2, 1, 1),
(2, 1, 2),
(2, 1, 3),
(2, 2, 0),
(2, 2, 1),
(2, 2, 2),
(2, 2, 3),
(2, 3, 0),
(2, 3, 1),
(2, 3, 2),
(2, 3, 3),
(3, 0, 0),
(3, 0, 1),
(3, 0, 2),
(3, 0, 3),
(3, 1, 0),
(3, 1, 1),
(3, 1, 2),
(3, 1, 3),
(3, 2, 0),
(3, 2, 1),
(3, 2, 2),
(3, 2, 3),
(3, 3, 0),
(3, 3, 1),
(3, 3, 2),
(3, 3, 3)]

 

Itérateur : permutations(P,n)

Rôle : renvoie toutes les permutations à n éléments prises dans le conteneur P

Exemple :

>>> list(permutations([1,2,3]))
[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]

>>> list(permutations([1,2,3],2))
[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]

>>> list(permutations("ABCD",3))
[('A', 'B', 'C'),
('A', 'B', 'D'),
('A', 'C', 'B'),
('A', 'C', 'D'),
('A', 'D', 'B'),
('A', 'D', 'C'),
('B', 'A', 'C'),
('B', 'A', 'D'),
('B', 'C', 'A'),
('B', 'C', 'D'),
('B', 'D', 'A'),
('B', 'D', 'C'),
('C', 'A', 'B'),
('C', 'A', 'D'),
('C', 'B', 'A'),
('C', 'B', 'D'),
('C', 'D', 'A'),
('C', 'D', 'B'),
('D', 'A', 'B'),
('D', 'A', 'C'),
('D', 'B', 'A'),
('D', 'B', 'C'),
('D', 'C', 'A'),
('D', 'C', 'B')]

 

Itérateur : combinations(P,n)

Rôle : renvoie toutes les combinaisons à n éléments sans doublons prises dans le conteneur P

Exemple :

>>> list(combinations([1,2,3],3))
[(1, 2, 3)]

>>> list(combinations([1,2,3],2))
[(1, 2), (1, 3), (2, 3)]

>>> list(combinations('abcdef',4))
[('a', 'b', 'c', 'd'),
('a', 'b', 'c', 'e'),
('a', 'b', 'c', 'f'),
('a', 'b', 'd', 'e'),
('a', 'b', 'd', 'f'),
('a', 'b', 'e', 'f'),
('a', 'c', 'd', 'e'),
('a', 'c', 'd', 'f'),
('a', 'c', 'e', 'f'),
('a', 'd', 'e', 'f'),
('b', 'c', 'd', 'e'),
('b', 'c', 'd', 'f'),
('b', 'c', 'e', 'f'),
('b', 'd', 'e', 'f'),
('c', 'd', 'e', 'f')]

>>> list(combinations(['a', 'b', 'c','d','e'], 3))
[('a', 'b', 'c'),
('a', 'b', 'd'),
('a', 'b', 'e'),
('a', 'c', 'd'),
('a', 'c', 'e'),
('a', 'd', 'e'),
('b', 'c', 'd'),
('b', 'c', 'e'),
('b', 'd', 'e'),
('c', 'd', 'e')]

Pour obtenir des listes et non des tuples :

for x in combinations(['a', 'b', 'c','d','e'], 3):
   print(list(x))

['a', 'b', 'c']
['a', 'b', 'd']
['a', 'b', 'e']
['a', 'c', 'd']
['a', 'c', 'e']
['a', 'd', 'e']
['b', 'c', 'd']
['b', 'c', 'e']
['b', 'd', 'e']
['c', 'd', 'e']

 

Itérateur : combinations_with_replacement(P,n)

Rôle : renvoie toutes les combinaisons à n éléments avec doublons prises dans le conteneur P

Exemple :

>>> list(combinations_with_replacement (['a', 'b', 'c'], 2))
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'b'), ('b', 'c'), ('c', 'c')]

>>> list(combinations_with_replacement (['a', 'b', 'c','d','e'], 3))
[('a', 'a', 'a'),
('a', 'a', 'b'),
('a', 'a', 'c'),
('a', 'a', 'd'),
('a', 'a', 'e'),
('a', 'b', 'b'),
('a', 'b', 'c'),
('a', 'b', 'd'),
('a', 'b', 'e'),
('a', 'c', 'c'),
('a', 'c', 'd'),
('a', 'c', 'e'),
('a', 'd', 'd'),
('a', 'd', 'e'),
('a', 'e', 'e'),
('b', 'b', 'b'),
('b', 'b', 'c'),
('b', 'b', 'd'),
('b', 'b', 'e'),
('b', 'c', 'c'),
('b', 'c', 'd'),
('b', 'c', 'e'),
('b', 'd', 'd'),
('b', 'd', 'e'),
('b', 'e', 'e'),
('c', 'c', 'c'),
('c', 'c', 'd'),
('c', 'c', 'e'),
('c', 'd', 'd'),
('c', 'd', 'e'),
('c', 'e', 'e'),
('d', 'd', 'd'),
('d', 'd', 'e'),
('d', 'e', 'e'),
('e', 'e', 'e')]

 

 

Retour au sommaire

Exemples de programmes

Génération de questions pour QCM en python

Algorithme pour tracer une rosace avec le module turtle d'EduPython

 

Retour au sommaire