Cette annexe est une carte de référence, pas un cours. Elle rassemble, en une page, la syntaxe et les fonctions vues dans les dix chapitres: une forme, une phrase qui dit ce qu'elle fait, un exemple minuscule et sa sortie réelle. Elle ne remplace aucun chapitre — elle sert le jour où vous savez ce que vous voulez faire et où seule l'écriture exacte vous échappe.
Tout ce qui est imprimé ici a été exécuté avec Python 3.13. Deux conventions d'affichage, celles des chapitres. Les lignes qui commencent par >>> sont une session interactive: ce qui suit la ligne est ce que l'interpréteur a répondu, et une expression seule y affiche sa valeur (dans un script, il faudrait un print). Les programmes de plus d'une ligne sont donnés dans un bloc, suivi d'un second bloc contenant leur sortie. Dans les traces d'erreur, le chemin complet du fichier est abrégé en son seul nom, pour tenir sur la page; tout le reste est reproduit tel quel.
Types et littéraux
Les neuf types du cours, avec leur écriture littérale. Le type d'une valeur se demande avec type(); il n'est jamais déclaré, il découle de ce que l'on écrit.
| Type | Nom français | Littéral | Modifiable |
|---|---|---|---|
int | entier | 20, -3, 0 | non |
float | nombre à virgule flottante | 1.75, -0.5, 1e-9 | non |
str | chaîne de caractères | "Alice", 'Alice' | non |
bool | booléen | True, False | non |
NoneType | absence de valeur | None | non |
list | liste | [4.5, 5.0, 3.5] | oui |
tuple | -uplet | (3, 4) | non |
dict | dictionnaire | {"Alice": 4.5} | oui |
set | ensemble | {"a", "e", "i"} | oui |
>>> age = 20
>>> taille = 1.75
>>> nom = "Alice"
>>> reussi = True
>>> rien = None
>>> type(age), type(taille), type(nom), type(reussi)
(<class 'int'>, <class 'float'>, <class 'str'>, <class 'bool'>)
>>> type(rien)
<class 'NoneType'>
>>> notes = [4.5, 5.0, 3.5]
>>> coord = (3, 4)
>>> carnet = {"Alice": 4.5, "Bruno": 5.0}
>>> lettres = {"a", "e", "i"}
>>> type(notes), type(coord), type(carnet), type(lettres)
(<class 'list'>, <class 'tuple'>, <class 'dict'>, <class 'set'>)
Les quatre structures vides s'écrivent [], (), {} et set(). Retenez la dernière: les accolades vides donnent un dictionnaire, pas un ensemble.
>>> [], (), {}, set()
([], (), {}, set())
>>> type({}), type(set())
(<class 'dict'>, <class 'set'>)
>>> 3, 3.0, "3"
(3, 3.0, '3')
>>> 3 == 3.0
True
>>> 3 == "3"
False
Conversions
int(), float() et str() servent aussi de convertisseurs. int() tronque vers zéro, il n'arrondit pas, et il refuse une chaîne qui contient un point.
>>> int("42"), float("4.5"), str(4.5)
(42, 4.5, '4.5')
>>> int(4.9), int(-4.9)
(4, -4)
>>> int("4.5")
Traceback (most recent call last):
File "<console>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '4.5'
>>> bool(0), bool(""), bool([]), bool("non")
(False, False, False, True)
La dernière ligne donne les valeurs «fausses» du langage: 0, 0.0, "", [], {}, set() et None. Tout le reste est vrai.
Opérateurs
Arithmétique
| Opérateur | Ce qu'il fait | Exemple |
|---|---|---|
+ - * | somme, différence, produit | 7 * 2 vaut 14 |
/ | division, toujours un float | 7 / 2 vaut 3.5 |
// | quotient entier (arrondi vers le bas) | 7 // 2 vaut 3 |
% | reste de la division entière | 7 % 2 vaut 1 |
** | puissance | 2 ** 0.5 vaut 1.414… |
+= -= *= | modifie la variable en place | total += 5 |
>>> 7 + 2, 7 - 2, 7 * 2
(9, 5, 14)
>>> 7 / 2
3.5
>>> 7 // 2, 7 % 2
(3, 1)
>>> 7 ** 2, 2 ** 0.5
(49, 1.4142135623730951)
>>> -7 // 2, -7 % 2
(-4, 1)
>>> 7.0 // 2
3.0
>>> 2 + 3 * 4, (2 + 3) * 4
(14, 20)
Deux remarques que le chapitre 1 détaille. // arrondit vers le bas et non vers zéro, d'où -7 // 2 qui vaut -4; et // sur un float rend un float. La priorité est celle de l'école: **, puis * / // %, puis + -; les parenthèses tranchent.
Comparaison, logique, appartenance
| Opérateur | Ce qu'il fait |
|---|---|
== != | égal, différent — rend un bool |
< <= > >= | inférieur, inférieur ou égal, supérieur, supérieur ou égal |
and or not | et, ou (inclusif), non — évaluation paresseuse |
in not in | appartenance à une chaîne, liste, dictionnaire, ensemble |
is is not | identité: est-ce le même objet? |
>>> 4.5 >= 4, 4.5 != 4, 3 < 4 < 5
(True, True, True)
>>> "Alice" < "Bruno"
True
>>> "Zoe" < "alice"
True
>>> True and False, True or False, not True
(False, True, False)
>>> 4 <= 4.5 and 4.5 <= 6
True
>>> "li" in "Alice", "z" in "Alice"
(True, False)
>>> 4.5 in [4.5, 5.0], "Alice" in {"Alice": 4.5}
(True, True)
Les chaînes se comparent caractère par caractère selon leur point de code: toutes les majuscules non accentuées précèdent toutes les minuscules, d'où "Zoe" < "alice". Sur un dictionnaire, in porte sur les clés. L'expression 3 < 4 < 5 est une comparaison enchaînée, qui signifie 3 < 4 and 4 < 5.
Que vaut l'expression 7 // 2 + 7 % 2 en Python?
Structures de contrôle
L'indentation est de la syntaxe: le corps d'un if, d'une boucle ou d'une fonction est constitué des lignes décalées sous l'en-tête, qui se termine par un deux-points. Quatre espaces par niveau, jamais de tabulation mêlée à des espaces.
| Forme | Ce qu'elle fait |
|---|---|
if condition: | exécute le bloc si la condition est vraie |
elif condition: | testé seulement si tous les tests précédents ont échoué |
else: | exécuté si aucun test n'a réussi |
while condition: | répète tant que la condition reste vraie (test avant le corps) |
for x in sequence: | répète une fois par élément de la séquence |
range(n) | les entiers de 0 à n - 1 |
range(a, b, p) | de a inclus à b exclu, par pas de p |
break | sort immédiatement de la boucle |
continue | abandonne le tour en cours et passe au suivant |
pass | ne fait rien; tient la place d'un bloc à écrire |
if, elif, else
note = 4.5
if note >= 5.5:
mention = "excellent"
elif note >= 4.0:
mention = "suffisant"
else:
mention = "insuffisant"
print(note, mention)
4.5 suffisant
Les tests sont examinés dans l'ordre et le premier qui réussit gagne: elif note >= 4.0 n'est atteint que si note >= 5.5 a échoué, ce qui rend inutile d'écrire elif 4.0 <= note < 5.5.
while
total = 0.0
combien = 0
notes = [4.5, 5.0, 3.5, 6.0, 4.0]
i = 0
while i < len(notes):
total += notes[i]
combien += 1
i += 1
print(combien, round(total / combien, 2))
5 4.6
Une boucle while correcte a toujours trois pièces: une initialisation avant la boucle, une condition qui porte sur ce qui change, et une progression dans le corps qui rapproche de la sortie. Oublier la troisième donne une boucle infinie, qu'on interrompt au clavier par Ctrl+C.
for et range
for i in range(3):
print(i, end=" ")
print()
print(list(range(3)), list(range(1, 4)), list(range(0, 10, 3)))
print(list(range(
0 1 2
[0, 1, 2] [1, 2, 3] [0, 3, 6, 9]
[3, 2, 1]
4.5
5.0
range(n) produit n valeurs, de 0 à n - 1: la borne est exclue. C'est la convention qui fait que range(len(liste)) parcourt exactement les indices valides, et c'est aussi la source de la moitié des erreurs d'indice du premier semestre.
break et continue
temperatures = [2.4, 5.1, 7.8, 6.2, 3.9, -0.5, 1.7]
premier_gel = 0
for jour in range(len(temperatures)):
if temperatures[jour] < 0:
premier_gel = jour + 1
break
print("premier gel:", premier_gel)
premier gel: 6
somme des jours sans gel: 27.1
Le motif du break est celui de la recherche: on s'arrête dès qu'on a trouvé, et une variable témoin initialisée à une valeur impossible (0 pour un numéro de jour) répond ensuite à la question «a-t-on trouvé?».
Fonctions
| Forme | Ce qu'elle fait |
|---|---|
def nom(p1, p2): | définit une fonction; ne l'exécute pas |
def nom(p, q=2): | q a une valeur par défaut, donc devient facultatif |
nom(3, q=5) | appel; q=5 est un argument nommé |
return valeur | rend la valeur et quitte la fonction |
return a, b | rend un tuple, que l'appelant peut dépaqueter |
"""…""" | docstring: première ligne du corps, dit ce que la fonction rend |
assert condition, message | vérifie une propriété; lève AssertionError si elle est fausse |
def moyenne(valeurs, arrondi=2):
"""Moyenne d'une liste non vide, a `arrondi` decimales."""
return round(sum(valeurs) / len(valeurs), arrondi)
notes = [4.5, 5.0, 3.5, 6.0, 4.0, 5.5, 4.5, 3.0, 5.0, 4.5]
print(moyenne(notes))
print(moyenne(notes, 1))
4.55
4.5
5.0
Moyenne d'une liste non vide, a `arrondi` decimales.
Ce sont les dix notes fictives du carnet du cours: somme 45,5, moyenne 4,55.
Une fonction sans return rend None. C'est la confusion la plus fréquente du chapitre 4: une fonction qui affiche un résultat ne le rend pas.
def est_suffisante(note):
if note >= 4.0:
return True
return False
def afficher(note):
print("note:", note)
print(est_suffisante(4.5), est_suffisante(3.0))
resultat = afficher(4.5)
print(resultat)
True False
note: 4.5
None
assert est le test du pauvre, et il suffit à ce cours: si la condition est fausse, le programme s'arrête en nommant l'assertion fautive.
def moyenne(valeurs):
return sum(valeurs) / len(valeurs)
assert moyenne([4.0, 6.0]) == 5.0
assert abs(moyenne([4.5, 5.0, 3.5]) - 4.333333) < 1e-6
print("les deux assertions passent")
assert moyenne([4.0, 6.0]) == 4.0,
les deux assertions passent
Traceback (most recent call last):
File "tests.py", line 7, in <module>
assert moyenne([4.0, 6.0]) == 4.0, "la moyenne de 4 et 6 vaut 5"
^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: la moyenne de 4 et 6 vaut 5
Notez la deuxième assertion: sur des flottants, on n'écrit jamais == 4.333333, on compare l'écart à une tolérance.
Portée. Un nom créé dans une fonction lui appartient et disparaît au retour; il ne modifie pas un nom global du même nom.
compteur = 0
def incrementer():
compteur = 1
return compteur
print(incrementer(), compteur)
1 0
Chaînes de caractères
Une chaîne est une suite de caractères immuable: on ne peut pas en modifier un caractère, seulement en fabriquer une nouvelle. s[i] est le caractère d'indice i, les indices commençant à 0; s[-1] est le dernier.
| Forme | Ce qu'elle rend |
|---|---|
s[i] | le caractère d'indice i |
s[a:b] | la tranche de a inclus à b exclu |
s[:b], s[a:], s[:] | début, fin, copie |
s[a:b:p] | tranche de pas p; s[::-1] renverse |
\n \t \\ \" | retour à la ligne, tabulation, barre, guillemet |
"""…""" | chaîne sur plusieurs lignes |
r"C:\notes" | chaîne brute: les barres ne sont plus des échappements |
>>> mot = "Programmation"
>>> len(mot)
13
>>> mot[0], mot[4], mot[-1]
('P', 'r', 'n')
>>> mot[0:6]
'Progra'
>>> mot[:6], mot[6:], mot[:]
('Progra', 'mmation', 'Programmation')
>>> mot[0:13:2]
'Pormain'
>>> mot[::-1]
'noitammargorP'
>>> mot[6:2]
''
>>> mot[20]
Traceback (most recent call last):
File "<console>", line 1, in <module>
IndexError: string index out of range
>>> mot[0] = "p"
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: 'str' object does not support item assignment
Une tranche vide ne provoque jamais d'erreur; un indice hors de la chaîne, si. C'est la différence à retenir entre mot[20] et mot[6:2].
Les méthodes du cours
Toutes rendent une nouvelle chaîne ou une valeur: aucune ne modifie s.
| Méthode | Ce qu'elle rend |
|---|---|
s.upper(), s.lower() | la chaîne tout en majuscules, tout en minuscules |
s.capitalize() | première lettre en majuscule, le reste en minuscules |
s.strip() | la chaîne sans espaces ni retours aux deux bouts |
s.replace(a, b) | la chaîne où chaque a est remplacé par b |
s.find(t) | l'indice de la première occurrence de t, ou -1 |
s.index(t) | idem, mais lève ValueError si t est absent |
s.count(t) | le nombre d'occurrences sans recouvrement de t |
s.split(sep) | la liste des morceaux; sans argument, découpe aux espaces |
sep.join(liste) | recolle une liste de chaînes avec sep entre elles |
s.startswith(t), s.endswith(t) | un booléen: commence par, finit par |
>>> ligne = " Alice ; 4.5 "
>>> ligne.strip()
'Alice ; 4.5'
>>> "alice".upper(), "ALICE".lower(), "alice".capitalize()
('ALICE', 'alice', 'Alice')
>>> "Alice;4.5".replace(";", " : ")
'Alice : 4.5'
>>> "Alice".find("ic"), "Alice".find("z")
(2, -1)
>>> "Alice;4.5;suffisant".split(";")
['Alice', '4.5', 'suffisant']
>>> "une phrase courte".split()
['une', 'phrase', 'courte']
>>> " - ".join(["Alice", "Bruno", "Chloe"])
'Alice - Bruno - Chloe'
>>> "notes.txt".startswith("notes"), "notes.txt".endswith(".csv")
(True, False)
>>> "mississippi".count("ss")
2
"mississippi".count("ss") rend 2 et non 3: les occurrences ne se recouvrent pas.
f-strings et formatage
Un f devant le guillemet ouvrant autorise des accolades contenant une expression, évaluée et insérée. Après un deux-points vient le format. Dans la colonne «Exemple» du tableau, chaque point médian · figure une espace réellement produite; la session qui suit le tableau montre les mêmes résultats entre crochets, sans artifice.
| Format | Effet | Exemple |
|---|---|---|
:.2f | notation décimale, deux décimales | 4.55 |
:.0% | pourcentage, zéro décimale | 80% |
:<10 | dix colonnes, aligné à gauche | Alice····· |
:>10 | dix colonnes, aligné à droite | ·····Alice |
:^10 | dix colonnes, centré | ··Alice··· |
:.<10 | remplissage par un point au lieu de l'espace | Alice..... |
:>6.2f | largeur et précision combinées | ··4.55 |
>>> nom = "Alice"
>>> moyenne = 4.55
>>> f"{nom} a {moyenne} de moyenne"
'Alice a 4.55 de moyenne'
>>> f"Moyenne: {moyenne:.2f}"
'Moyenne: 4.55'
>>> f"Moyenne: {moyenne:.1f}"
'Moyenne: 4.5'
>>> f"Reussite: {0.8:.0%}"
'Reussite: 80%'
>>> f"[{nom:<10}]"
'[Alice ]'
>>> f"[{nom:>10}]"
'[ Alice]'
>>> f"[{nom:^10}]"
'[ Alice ]'
>>> f"[{nom:.<10}]"
'[Alice.....]'
>>> f"{nom:<10}{moyenne:>6.2f}"
'Alice 4.55'
>>> f"2 + 3 fait {2 + 3}"
'2 + 3 fait 5'
La troisième ligne surprend: 4.55 affiché avec une décimale donne 4.5, pas 4.6. Le flottant le plus proche de 4,55 est légèrement inférieur à 4,55, et l'arrondi le suit. Un affichage arrondi n'est pas un arrondi mathématique.
Que rend l'expression «Alice».find(«z») lorsque la lettre cherchée est absente?
Listes
Une liste est une suite modifiable d'éléments, indexée comme une chaîne. Elle se construit par un littéral, par list() sur une séquence, par répétition ou par concaténation.
>>> notes = [4.5, 5.0, 3.5, 6.0, 4.0]
>>> len(notes), notes[0], notes[-1]
(5, 4.5, 4.0)
>>> notes[1:3], notes[:2], notes[::-1]
([5.0, 3.5], [4.5, 5.0], [4.0, 6.0, 3.5, 5.0, 4.5])
>>> notes[2] = 3.0
>>> notes
[4.5, 5.0, 3.0, 6.0, 4.0]
>>> list("abc"), list(range(4))
(['a', 'b', 'c'], [0, 1, 2, 3])
>>> [0] * 5
[0, 0, 0, 0, 0]
>>> [1, 2] + [3]
[1, 2, 3]
La ligne notes[2] = 3.0 est toute la différence avec une chaîne: une liste se modifie en place.
| Méthode | Ce qu'elle fait | Ce qu'elle rend |
|---|---|---|
l.append(x) | ajoute x à la fin | None |
l.insert(i, x) | insère x à l'indice i | None |
l.extend(autre) | ajoute tous les éléments de autre | None |
l.remove(x) | retire la première occurrence de x | None |
l.pop() | retire et rend le dernier élément | l'élément |
l.pop(i) | retire et rend l'élément d'indice i | l'élément |
l.index(x) | l'indice de la première occurrence | l'indice |
l.count(x) | le nombre d'occurrences | le compte |
l.sort() | trie la liste en place | None |
l.reverse() | renverse la liste en place | None |
l.copy() | une copie de surface | la copie |
>>> notes = [4.5, 5.0, 3.5]
>>> notes.append(6.0)
>>> notes
[4.5, 5.0, 3.5, 6.0]
>>> notes.insert(0, 4.0)
>>> notes
[4.0, 4.5, 5.0, 3.5, 6.0]
>>> notes.extend([5.5, 4.5])
>>> notes
[4.0, 4.5, 5.0, 3.5, 6.0, 5.5, 4.5]
>>> notes.remove(3.5)
>>> notes
[4.0, 4.5, 5.0, 6.0, 5.5, 4.5]
>>> notes.pop()
4.5
>>> notes.pop(0)
4.0
>>> notes
[4.5, 5.0, 6.0, 5.5]
>>> notes.index(5.0), notes.count(4.5)
(1, 1)
Aliasing et copie
b = a ne copie pas la liste: il donne un second nom au même objet.
>>> a = [1, 2, 3]
>>> b = a
>>> b.append(4)
>>> a
[1, 2, 3, 4]
>>> c = a.copy()
>>> c.append(5)
>>> a, c
([1, 2, 3, 4], [1, 2, 3, 4, 5])
>>> d = a[:]
>>> d is a, d == a
(False, True)
Les trois façons de copier une liste sont a.copy(), a[:] et list(a). Toutes trois sont des copies de surface: pour une liste de listes, les sous-listes restent partagées.
Listes en compréhension
[expression for x in sequence if condition] construit une liste en une ligne. Le if est facultatif.
>>> notes = [4.5, 5.0, 3.5, 6.0, 4.0]
>>> [n + 0.5 for n in notes]
[5.0, 5.5, 4.0, 6.5, 4.5]
>>> [n for n in notes if n >= 4.5]
[4.5, 5.0, 6.0]
>>> [n * n for n in range(1, 6)]
[1, 4, 9, 16, 25]
>>> [len(m) for m in ["Alice", "Bruno", "Chloe"]]
[5, 5, 5]
Tuples
Un tuple est une liste immuable. On s'en sert pour ce qui ne doit pas changer, pour rendre plusieurs valeurs d'une fonction, et comme clé de dictionnaire.
>>> point = (3, 4)
>>> point[0], len(point)
(3, 2)
>>> x, y = point
>>> x, y
(3, 4)
>>> solo = (5,)
>>> type(solo), type((5))
(<class 'tuple'>, <class 'int'>)
>>> point[0] = 9
Traceback (most recent call last):
File "<console>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
C'est la virgule qui fait le tuple, pas les parenthèses: (5) est l'entier cinq, (5,) est un tuple d'un élément. Le dépaquetage x, y = point permet aussi l'échange en une ligne, a, b = b, a.
def extremes(valeurs):
return min(valeurs), max(valeurs)
bas, haut = extremes([4.5, 5.0, 3.5, 6.0])
print(bas, haut)
print(extremes([4.5, 5.0]))
3.5 6.0
(4.5, 5.0)
Dictionnaires et ensembles
Un dictionnaire associe des clés à des valeurs. L'accès par clé est immédiat, quelle que soit la taille; une clé doit être immuable (chaîne, nombre, tuple).
| Forme | Ce qu'elle fait |
|---|---|
d[cle] | la valeur associée; lève KeyError si la clé est absente |
d[cle] = v | ajoute la clé, ou remplace sa valeur |
d.get(cle) | la valeur, ou None si la clé est absente |
d.get(cle, defaut) | la valeur, ou defaut si la clé est absente |
cle in d | un booléen: cette clé est-elle présente? |
del d[cle] | supprime la clé |
d.pop(cle) | supprime la clé et rend sa valeur |
d.keys(), d.values(), d.items() | vues des clés, des valeurs, des couples |
len(d) | le nombre de clés |
>>> notes = {"Alice": 4.5, "Bruno": 5.0, "Chloe": 3.5}
>>> notes["Alice"]
4.5
>>> notes["Zoe"]
Traceback (most recent call last):
File "<console>", line 1, in <module>
KeyError: 'Zoe'
>>> notes.get("Zoe"), notes.get("Zoe", 0.0)
(None, 0.0)
>>> "Bruno" in notes, "Zoe" in notes
(True, False)
>>> notes["David"] = 6.0
>>> notes["Alice"] = 5.0
>>> notes
{'Alice': 5.0, 'Bruno': 5.0, 'Chloe': 3.5, 'David': 6.0}
>>> del notes["Chloe"]
>>> notes.pop("Bruno")
5.0
>>> notes
{'Alice': 5.0, 'David': 6.0}
Les trois vues servent au parcours; items() rend des couples que la boucle dépaquette directement. Les clés sont parcourues dans leur ordre d'insertion.
>>> notes = {"Alice": 4.5, "Bruno": 5.0, "Chloe": 3.5}
>>> list(notes.keys())
['Alice', 'Bruno', 'Chloe']
>>> list(notes.values())
[4.5, 5.0, 3.5]
>>> list(notes.items())
[('Alice', 4.5), ('Bruno', 5.0), ('Chloe', 3.5)]
>>> sum(notes.values()) / len(notes)
4.333333333333333
>>> max(notes, key=notes.get)
'Bruno'
>>> {nom: note + 0.5 for nom, note in notes.items()}
{'Alice': 5.0, 'Bruno': 5.5, 'Chloe': 4.0}
Le motif de comptage, à connaître par cœur: get(cle, 0) + 1 fournit le zéro de départ sans qu'on ait à tester la présence de la clé.
notes = {"Alice": 4.5, "Bruno": 5.0, "Chloe": 3.5}
for nom in notes:
print(nom, end=" ")
print()
for nom, note in notes.items():
print(f"{nom:<8}{note:>5.1f}")
texte
Alice Bruno Chloe
Alice 4.5
Bruno 5.0
Chloe 3.5
{'m': 1, 'i': 4, 's': 4, 'p': 2}
Ensembles
Un ensemble est un dictionnaire dont on aurait retiré les valeurs: éléments uniques, aucun ordre, appartenance immédiate. Il s'écrit avec des accolades, mais l'ensemble vide est set(). Les quatre opérations s'écrivent avec des symboles: union (barre verticale), intersection (&), différence (-) et différence symétrique (^).
>>> a = {1, 2, 3, 4}
>>> b = {3, 4, 5}
>>> a | b
{1, 2, 3, 4, 5}
>>> a & b
{3, 4}
>>> a - b
{1, 2}
>>> a ^ b
{1, 2, 5}
>>> a.add(9)
>>> a.discard(1)
>>> sorted(a)
[2, 3, 4, 9]
>>> set([1, 1, 2, 2, 3])
{1, 2, 3}
>>> set("mississippi") == {"m", "i", "s", "p"}
True
>>> 3 in a, 7 in a
(True, False)
add ajoute, discard retire sans se plaindre si l'élément est absent, et set(liste) est la façon la plus courte de supprimer les doublons. Affichez un ensemble avec sorted() si vous voulez une sortie reproductible.
| Structure | Quand la choisir |
|---|---|
list | l'ordre compte, ou les doublons sont légitimes |
tuple | la valeur ne doit pas changer, ou sert de clé |
dict | chaque donnée a un identifiant naturel |
set | seule la présence compte, les doublons sont à éliminer |
Le dictionnaire d ne contient pas la clé «Zoe». Quelle expression rend 0.0 au lieu de lever une erreur?
Fonctions natives
Disponibles partout, sans importation.
| Fonction | Ce qu'elle fait |
|---|---|
print(a, b, …) | affiche; sep= sépare les valeurs, end= termine la ligne |
input(invite) | affiche l'invite, lit une ligne, rend une chaîne |
len(x) | longueur d'une chaîne, liste, tuple, dict ou set |
range(a, b, p) | la suite des entiers de a à b exclu, par pas p |
int(x), float(x), str(x) | conversions |
bool(x) | valeur de vérité de x |
abs(x) | valeur absolue |
round(x, n) | arrondi à n décimales; sans n, rend un int |
min(…), max(…) | le plus petit, le plus grand |
sum(sequence) | la somme des éléments |
sorted(sequence) | une nouvelle liste triée; reverse=, key= |
enumerate(sequence) | les couples (indice, element); start= change l'origine |
zip(a, b) | les couples (a[i], b[i]), jusqu'au plus court |
list(x), tuple(x), set(x), dict(x) | conversions de structure |
type(x) | le type de x |
help(objet) | la documentation de l'objet, dans l'interpréteur |
open(chemin, mode) | ouvre un fichier |
ord(c), chr(n) | point de code et caractère |
>>> abs(-4.5), abs(3)
(4.5, 3)
>>> round(4.55, 1), round(4.567, 2), round(4.5), round(5.5)
(4.5, 4.57, 4, 6)
>>> min(4.5, 3.0), max([4.5, 5.0, 3.5])
(3.0, 5.0)
>>> sum([4.5, 5.0, 3.5]), sum([1, 2, 3])
(13.0, 6)
>>> len("Alice"), len([1, 2, 3]), len({"a": 1})
(5, 3, 1)
>>> sorted("banane")
['a', 'a', 'b', 'e', 'n', 'n']
>>> sorted([4.5, 5.0, 3.5], reverse=True)
[5.0, 4.5, 3.5]
>>> sorted(["Chloe", "alice", "Bruno"], key=str.lower)
['alice', 'Bruno', 'Chloe']
>>> list(enumerate(["Alice", "Bruno"]))
[(0, 'Alice'), (1, 'Bruno')]
>>> list(enumerate(["Alice", "Bruno"], start=1))
[(1, 'Alice'), (2, 'Bruno')]
>>> list(zip(["Alice", "Bruno"], [4.5, 5.0]))
[('Alice', 4.5), ('Bruno', 5.0)]
Regardez round(4.5) et round(5.5): 4 et 6. Python arrondit les demis vers le pair, ce qui évite un biais systématique quand on somme beaucoup d'arrondis. Ce n'est pas la règle apprise à l'école, et c'est le comportement correct.
enumerate et zip sont les deux façons propres de parcourir avec un indice et de parcourir deux listes de front, sans manipuler range(len(...)).
noms = ["Alice", "Bruno", "Chloe"]
notes = [4.5, 5.0, 3.5]
for rang, nom in enumerate(noms, start=1):
print(rang, nom)
for nom, note in zip(noms, notes):
print(f"{nom:<8}{note:>5.1f}
1 Alice
2 Bruno
3 Chloe
Alice 4.5
Bruno 5.0
Chloe 3.5
print accepte plusieurs valeurs et deux paramètres nommés; input rend toujours une chaîne, qu'il faut convertir.
print("Alice", 4.5, True)
print("Alice", 4.5, sep=" ; ")
print("sans retour", end=" | ")
print("suite")
Alice 4.5 True
Alice ; 4.5
sans retour | suite
note = float(input("Note : "))
print("le double vaut", note * 2)
Note : 4.5
le double vaut 9.0
Dans cette dernière sortie, 4.5 est la ligne tapée par l'utilisateur, pas un affichage du programme.
Enfin, help donne la documentation d'une fonction sans quitter l'interpréteur:
>>> help(abs)
Help on built-in function abs in module builtins:
abs(x, /)
Return the absolute value of the argument.
Fichiers
On n'ouvre pas un fichier autrement qu'avec with: le bloc garantit la fermeture, même si une erreur l'interrompt.
| Mode | Nom | Le fichier n'existe pas | Le fichier existe |
|---|---|---|---|
"r" | lecture | FileNotFoundError | il est lu depuis le début |
"w" | écriture | il est créé, vide | son contenu est effacé |
"a" | ajout | il est créé, vide | on écrit à la fin, rien n'est perdu |
| Forme | Ce qu'elle fait |
|---|---|
with open(c, "r") as f: | ouvre c en lecture, ferme à la sortie du bloc |
f.read() | tout le contenu, en une seule chaîne |
f.readlines() | la liste des lignes, retours à la ligne compris |
for ligne in f: | une ligne par tour, sans tout charger en mémoire |
f.write(texte) | écrit texte; n'ajoute pas de retour à la ligne |
with open("temperatures.txt", "w") as f:
for t in [2.4, 5.1, 7.8, 6.2, 3.9, -0.5, 1.7]:
f.write(str(t) + "\n")
with open("temperatures.txt", "r") as f:
contenu
'2.4\n5.1\n7.8\n6.2\n3.9\n'
7 3.8
Ce sont les sept températures fictives du cours; leur moyenne est bien 3,80 °C. Notez le strip() avant le float(): chaque ligne lue se termine par un \n dont la conversion ne veut pas.
with open("temperatures.txt", "a") as f:
f.write("9.9\n")
with open("temperatures.txt", "r") as f:
lignes = f.readlines()
print(len(lignes), repr(lignes[-1]))
8 '9.9\n'
Un fichier absent produit une erreur nommée, que la section suivante apprend à intercepter:
Traceback (most recent call last):
File "lecture.py", line 1, in <module>
with open("absent.txt", "r") as f:
~~~~^^^^^^^^^^^^^^^^^^^
FileNotFoundError: [Errno 2] No such file or directory: 'absent.txt'
Pour un fichier tabulaire, ligne.strip().split(";") suffit tant que les champs ne contiennent pas le séparateur; au-delà, le module csv de la bibliothèque standard fait le travail correctement.
Exceptions
| Bloc | Quand il s'exécute |
|---|---|
try: | toujours, mais interrompu dès qu'une exception y est levée |
except X: | seulement si une exception de type X a été levée dans le try |
except X as e: | idem, et e désigne l'exception (son message s'affiche) |
else: | seulement si le try s'est terminé sans aucune exception |
finally: | dans tous les cas, en dernier, même si personne n'a attrapé |
raise X("message") | lève soi-même une exception |
def lire_note(texte):
try:
note = float(texte)
except ValueError:
print(" except : conversion impossible")
return None
else:
print(" else : conversion reussie")
return note
finally:
print(" finally: toujours execute")
print(lire_note("4.5"))
print(lire_note("quatre"
else : conversion reussie
finally: toujours execute
4.5
except : conversion impossible
finally: toujours execute
None
Le finally passe avant le retour de la fonction: c'est sa raison d'être. Plusieurs except peuvent se suivre, et le premier dont le type correspond gagne.
for texte in ["12", "zero", "0"]:
try:
valeur = int(texte)
print(100 / valeur)
except ValueError:
print("pas un entier:", texte)
except ZeroDivisionError:
print("division par zero")
8.333333333333334
pas un entier: zero
division par zero
raise sert à refuser une donnée invalide là où on la détecte, en laissant l'appelant décider quoi en faire.
def verifier(note):
if note < 1.0 or note > 6.0:
raise ValueError(f"note hors de l'echelle suisse: {note}")
return note
print(verifier(4.5))
try:
verifier(7.0)
except ValueError as erreur:
print("attrapee:", erreur)
verifier(
4.5
attrapee: note hors de l'echelle suisse: 7.0
Traceback (most recent call last):
File "notes.py", line 11, in <module>
verifier(0.5)
~~~~~~~~^^^^^
File "notes.py", line 3, in verifier
raise ValueError(f"note hors de l'echelle suisse: {note}")
ValueError: note hors de l'echelle suisse: 0.5
Les exceptions rencontrées dans le cours:
| Nom | Ce qui l'a provoquée |
|---|---|
SyntaxError | le code n'est pas du Python; rien n'a été exécuté |
IndentationError | indentation absente ou incohérente |
NameError | un nom utilisé avant d'exister — souvent une faute de frappe |
TypeError | une opération entre types incompatibles |
ValueError | le bon type, mais une valeur impossible |
ZeroDivisionError | une division ou un modulo par zéro |
IndexError | un indice hors de la séquence |
KeyError | une clé absente du dictionnaire |
AttributeError | une méthode qui n'existe pas pour ce type |
FileNotFoundError | un fichier ouvert en lecture et introuvable |
UnboundLocalError | un nom local lu avant d'avoir été affecté |
AssertionError | une assertion fausse |
RecursionError | une récursion trop profonde, souvent sans cas de base |
Modules
| Forme | Effet |
|---|---|
import math | rend le module accessible sous son nom: math.sqrt |
from math import sqrt, pi | importe deux noms précis, utilisables sans préfixe |
import math as m | importe sous un alias: m.floor |
from math import * | à éviter: on ne sait plus d'où vient quoi |
>>> import math
>>> math.sqrt(2), math.pi
(1.4142135623730951, 3.141592653589793)
>>> math.floor(3.8), math.ceil(3.2)
(3, 4)
>>> round(math.log(100, 10), 6), round(math.exp(1), 4)
(2.0, 2.7183)
>>> from math import sqrt, pi
>>> sqrt(9), round(pi, 4)
(3.0, 3.1416)
>>> import math as m
>>> m.floor(-3.2)
-4
>>> import random
>>> random.seed(42)
>>> random.randint(1, 6)
6
>>> random.random()
0.11133106816568039
>>> random.choice(["Alice", "Bruno", "Chloe"])
'Chloe'
>>> tirage = [1, 2, 3, 4, 5]
>>> random.shuffle(tirage)
>>> tirage
[4, 5, 1, 2, 3]
random.seed(42) fixe la graine: la même graine redonne exactement la même suite de tirages, ce qui rend un programme aléatoire reproductible — indispensable pour le tester. Les quatre modules standard du cours sont math, random, csv et sys.
Un module est un fichier .py; son nom est celui du fichier sans l'extension. Ne nommez jamais un de vos fichiers math.py, random.py ou csv.py: il masquerait le module standard. Voici deux fichiers placés dans le même dossier, statistiques.py d'abord:
"""Statistiques elementaires sur une liste de nombres."""
def moyenne(valeurs):
"""Moyenne arithmetique. Leve ValueError si la liste est vide."""
if len(valeurs) == 0:
raise ValueError("liste vide: pas de moyenne")
return sum(valeurs) / len(valeurs)
if __name__ == "__main__":
print("auto-test:", moyenne([4.0, 6.0]))
puis principal.py, qui l'importe:
import statistiques
notes = [4.5, 5.0, 3.5, 6.0, 4.0, 5.5, 4.5, 3.0, 5.0, 4.5]
print("moyenne:", round(statistiques.moyenne(notes), 2))
Lancé directement par python3 statistiques.py, le premier fichier exécute son auto-test:
auto-test: 5.0
Lancé par python3 principal.py, le second affiche la moyenne des dix notes du cours — et aucune trace de l'auto-test, parce que __name__ ne vaut "__main__" que dans le fichier lancé:
moyenne: 4.55
Les conventions de ce cours
| Convention | Pourquoi |
|---|---|
snake_case pour les variables et les fonctions | note_max, compter_voyelles: c'est l'usage de tout le code Python, et le nom reste lisible |
| identifiants français sans accents | moyenne, temperatures, eleve: ce que vous écrivez et ce que votre enseignant lit, sans qu'un accent se glisse dans un nom |
| commentaires en français, mots-clés en anglais | for, while, True sont du Python et ne se traduisent pas |
| dans le code, le point décimal | 4.55 dans un programme, «4,55» dans une phrase: ce sont deux écritures pour deux contextes |
| flottants comparés avec une tolérance | abs(a - b) < 1e-9 et jamais a == b: 0.1 + 0.2 ne vaut pas 0.3 |
| une sortie affichée est une sortie exécutée | le lecteur lancera le programme; une trace inventée se voit immédiatement |
| aucune bibliothèque extérieure | math, random, csv, sys suffisent aux dix chapitres |
python3 --version doit afficher 3.11 ou plus | les messages d'erreur soulignés et les formulations de ce cours en dépendent |
Références
- Documentation officielle Python, The Python Language Reference et The Python Standard Library, sections «Built-in Functions», «Built-in Types» et «Format Specification Mini-Language» (docs.python.org). La référence exacte pour tout ce qui est résumé ici.
- Le tutoriel officiel Python (docs.python.org), sections «An Informal Introduction to Python», «More Control Flow Tools» et «Errors and Exceptions».
- A. Downey, Think Python, 3e éd., O'Reilly. Les annexes de dépannage et le glossaire complètent utilement cette carte.
- G. Swinnen, Apprendre à programmer avec Python 3, Eyrolles. Les tableaux de méthodes de chaîne et de liste, en français.
- E. Matthes, Python Crash Course, 3e éd., No Starch Press. La première partie sert de mémento illustré, avec ses propres aide-mémoire.