Librement inspiré des supports de cours de Gaël Guibon
Librement inspiré des supports de cours de Julien PillaRetrouver l'ensemble du cours sur 👉 github.com/alix-tz/enc-intro-algo👈
👉 Simulateur d'environnement Python en mode pseudo-IDE : https://repl.it/languages/python3
👉 Simulateur d'environnement Python en mode console : https://www.python.org/shell/
👉 Documentation officielle de Python : https://docs.python.org/3/
👉 Visualisateur d'exécution de code Python : http://pythontutor.com/
👉 "Automate the Boring Stuff with Python" (en
) : https://automatetheboringstuff.com/
👉 Leçons dédiées à Python sur Programming Historian (en
, fr
ou es
) : https://programminghistorian.org/en/lessons/introduction-and-installation
👉 "Apprendre à coder avec Python", MOOC de l'Université Libre de Bruxelles (fr
) : https://www.fun-mooc.fr/courses/course-v1:ulb+44013+session04/about
👉 "Apprenez à programmer en Python", cours en ligne sur OpenClassroom (fr
) : https://openclassrooms.com/fr/courses/235344-apprenez-a-programmer-en-python
👉 "Introduction à Python" pour le Master Ingénierie Multilingue de l'Inalco, Loïc Grobol et Yoann Dupont (fr
) : https://loicgrobol.github.io/python-im/m2-2018/
Une fonction
est une suite d'instructions rassemblées sous un nom et que l'on peut appeler dans un programme. On dit qu'une fonction renvoie ou retourne
une valeur une fois que l'ensemble des instructions qu'elle contient ont été exécutées. Cette valeur peut être nulle (None
) ou essentielle à l'exécution du reste du programme.
On a vu qu'il existe des fonctions built-in
(ex : print()
), mais l'utilisateur-rice peut aussi créer ses propres fonctions, souvent pour simplifier le code en créant des unités logiques.
Pour créer une fonction, on utilise le mot-clef def
suivi du nom que l'on souhaite donner à la fonction, suivi de parenthèses puis de deux points (():
). Pour mettre fin à la déclaration de la fonction, on utilise le mot-clef return
. Il peut être suivi d'une valeur ou être utilisé seul
Les instructions décrites à l'intérieur d'une fonction ne sont pas exécutées tant que la fonction n'est pas appelée. Pour appeler une fonction
on utilise son nom, suivi de parenthèses. Une fonction peut appeler une autre fonction.
Je crée une fonction nommée dit_coucou dont le seul but est d'afficher "Coucou !".
# je crée une fonction
def dit_coucou():
print("Coucou !")
return
# j'appelle la fonction
dit_coucou()
Coucou !
En Python, les trois déclarations suivantes mènent au même résultat :
def dit_coucou():
print("Coucou !")
return None
def dit_coucou():
print("Coucou !")
return
def dit_coucou():
print("Coucou !")
Cela signifie qu'en Python, le mot-clef return
n'est pas obligatoire si l'on ne renvoie pas de valeur à la fin de la fonction. En fait, la fin de l'indentation suffit à signaler la fin de la déclaration de la fonction.
Quand une fonction renvoie une valeur, on peut la stocker dans une variable pour l'utiliser ensuite.
def combien_font_trois_plus_trois():
return 3 + 3
resultat = combien_font_trois_plus_trois() # on peut stocker le résultat
print(combien_font_trois_plus_trois()) # ou interagir avec directement
6
Les parenthèses ne sont pas ici pour faire joli. Comme avec les fonctions en mathématiques, elles servent à faire passer une ou plusieurs valeurs (arguments
ou paramètres
) qui seront utilisées pour exécuter les instructions définies dans la fonction.
Les arguments sont en quelque sorte des variables qui n'existent que durant le temps d'exécution de la fonction. Pour désigner ce phénomène, on parle de la portée (scope
) d'une variable.
def dit_moi_coucou(nom):
print("Coucou", nom, "!")
mon_prenom = "Alix"
dit_moi_coucou(mon_prenom)
Coucou Alix !
Si j'essaie de faire appel à la variable nom
en dehors du bloc de définition de la fonction "dit_moi_coucou", ça ne fonctionne pas
print(nom)
--------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-10-c427005c1d14> in <module> ----> 1 print(nom) NameError: name 'nom' is not defined
On a parlé de définition de fonction
, d'appel de fonction
, d'arguments
, de renvois
et de scope
.
def afficher_lavariable_son_type_et_sa_valeur(lavariable):
print("la variable", type(lavariable), lavariable, sep=" | ")
return "C'est fait!"
le_nom_de_mon_chat = "Query"
print(afficher_lavariable_son_type_et_sa_valeur(le_nom_de_mon_chat))
la variable | <class 'str'> | Query C'est fait!
reçoit
une valeur dans une variable nommée lavariableIl n'y a pas de règle qui définisse qu'à tel ou tel moment il faut créer une fonction. C'est une affaire de pratique, de choix dans l'organisation du code et de lisibilité de celui-ci.
Souvent, on fait une fonction pour un ensemble logique d'actions.
Par exemple dans un programme qui génère des tweets illustrés, une fonction crée un texte et une image, une fonction enregistre l'image localement, une fonction envoie le texte et l'image sur Twitter. Décomposer ainsi le code permet de faire ressortir les grandes étapes de traitement.
Souvent, aussi, on crée une fonction que l'on réutilisera par la suite dans d'autres projets, on évite ainsi de recréer un élément du code qu'on a déjà rédigé.
Par exemple, une fonction pour lister l'ensemble des fichiers contenus dans un dossier.
Pour faciliter la lecture d'un script, on rassemble l'ensemble des définitions de fonction avant de passer au groupe d'instruction principal, qui contiendra les appels de fonctions.
# définition de la fonction 1
# définition de la fonction 2
# définition de la fonction 3
# --------
# instructions
# appel de la fonction 1
# instructions
# appel de la fonction 1
# appel de la fonction 3
# instructions
# appel de la fonction 2
Faire les 5 exercices du fichier fonctions.py
À part les fonctions built-in et les fonctions créées de toutes pièces, il est possible d'utiliser des fonctions déjà définies par d'autres développeur·ses.
Pour faire simple, ces fonctions sont enregistrées dans des libraries (ou package) que l'on importe
dans un programme pour pouvoir s'en servir. On parle aussi de dépendances
.
Certaines libraries sont built-ins : elles sont toujours disponibles, il suffit de les activer. D'autres doivent être installées avant de pouvoir être activées. On utilise pour cela un gestionnaire de paquets
(comme pip).
Quelques exemples de libraries built-in que vous rencontrerez rapidement : os
, csv
, random
.
Pour activer une library, il suffit de l'importer au tout début du script avec le mot-clef import
, suivi du nom de la library.
import os # on peut désormais utiliser les fonctions de la library os.
import random # on peut désormais utiliser les fonctions de la library random.
Pour utiliser une fonction issue d'une library, il faut rappeler son nom, puis appeler le nom de la fonction comme on le ferait avec une fonction définie localement.
Cela se fait selon le modèle suivant : nom_du_paquet.nom_de_la_fonction()
# random possède une fonction appelée randint() qui permet de générer un nombre entier au hasard
# compris entre a et b.
print(random.randint(0, 100))
82
Pour faciliter la lecture d'un script, les imports se font au tout début du script.
# imports
# --------
# définition de la fonction 1
# définition de la fonction 2
# définition de la fonction 3
# --------
# instructions
# appel de la fonction 1
# instructions
# appel de la fonction 1
# appel de la fonction 3
# instructions
# appel de la fonction 2
📜 Les listes sont un type de variable pouvant contenir une ou plusieurs valeurs à la suite.
📜🐍 En Python, une liste peut contenir plusieurs types de variables en même temps.
📜🤨 En fonction des langages de programmation, on les appelle aussi array
ou vecteur
.
📜 Une liste est un objet appartenant à la catégorie des iterables
(comme les chaines de caractères)
📜 Les valeurs contenues dans une liste sont indexées
. On peut donc cibler précisément telle ou telle valeur contenue dans la liste.
📜🤯 L'indexation dans une liste commence à 0
# créer une liste
ma_liste_vide = []
mon_autre_liste_vide = list()
ma_liste = ['A','B','C','D']
# Accéder au contenu d'une liste
print('ma_liste[2] :', ma_liste[2])
une_variable = ma_liste[1]
print('une_variable :', une_variable)
# Une liste peut contenir plusieurs types... y compris des listes
super_liste = ["ceci n'est pas un chiffre", 3.14, True, type('hello'), 2048, ma_liste]
print('super_liste :', super_liste)
ma_liste[2] : C une_variable : B super_liste : ["ceci n'est pas un chiffre", 3.14, True, <class 'str'>, 2048, ['A', 'B', 'C', 'D']]
Moyen mnémotechnique : l'indexation des listes fonctionne comme les étages en France.
index | 0 | 1 | 2 | 3 |
---|---|---|---|---|
valeur | A | B | C | D |
palier | RDC | 1E | 2E | 3E |
Si vous demandez un index qui n'est pas associé à une valeur (parce que la liste est trop courte), vous obtenez une erreur (IndexError
).
print(ma_liste[4])
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-15-b214c2428d1f> in <module> ----> 1 print(ma_liste[4]) IndexError: list index out of range
On peut viser un emplacement dans la liste en partant du début ou de la fin.
liste_exemple = ["RDC", "1er", "2e", "3e", "4e"]
print(liste_exemple[-1])
print(liste_exemple[-3])
4e 2e
print(liste_exemple[-10])
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-17-c4b99e6a1b85> in <module> ----> 1 print(liste_exemple[-10]) IndexError: list index out of range
Pour éviter les déconvenues, pensez à utiliser len()
sur une liste avant de cibler les valeurs indexées.
print(len(liste_exemple))
5
print(liste_exemple[len(liste_exemple) - 1])
4e
index = 6
if index < len(liste_exemple):
print(liste_exemple[index])
else:
print("No can't do!")
No can't do!
sublists
ou encore slices
¶Si on peut cibler une seule valeur à la fois, on peut aussi cibler une section dans une liste : liste[début:fin:pas]
exemple = ['p','y','t','h','o','n', ' ', '!']
print(exemple[2:6])
['t', 'h', 'o', 'n']
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
"P" | "Y" | "T" | "H" | "O" | "N" | " " | "!" |
- | - | start | - | - | - | stop | - |
# on peut utiliser des index négatifs
print('1 :', exemple[-6:-2])
1 : ['t', 'h', 'o', 'n']
# en parcourant la liste de gauche à droite
print('2 :', exemple[-2:-6])
2 : []
# le pas de 1 est implicite, on peut le modifier
print('3 :', exemple[2:6:2])
3 : ['t', 'o']
# sans index de fin, on continue jusqu'à la fin de la liste
print('4 :', exemple[2:])
4 : ['t', 'h', 'o', 'n', ' ', '!']
# sans index de début, on part du début de la liste
print('5 :', exemple[:5])
5 : ['p', 'y', 't', 'h', 'o']
# on peut faire une section allant du début à la fin (copie)
print('6 :', exemple[:])
6 : ['p', 'y', 't', 'h', 'o', 'n', ' ', '!']
# on peut ne préciser que le pas
print('7 :', exemple[::2])
7 : ['p', 't', 'o', ' ']
# n'importe lequel des éléments peut être implicite
print('8 :', exemple[:5:2])
8 : ['p', 't', 'o']
Une chaîne de caractères fait aussi partie de la catégorie des itérables, on peut donc se servir des slices et des index sur ce type de valeur.
chaine = 'python !'
print(chaine[len(chaine) - (len(chaine)*2)])
print(chaine[2:6])
p thon
En revanche, dans une chaîne de caractères, on ne peut pas réassigner une valeur à un index. On dit qu'une chaîne de caractères est immutable
.
chaine[4] = '*'
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-24-b6a7f31ceb5f> in <module> ----> 1 chaine[4] = '*' TypeError: 'str' object does not support item assignment
# mais on peut toujours contourner ce problème...
modif = chaine[:3] + '*' + chaine[4:]
print(modif)
pyt*on !
Les listes ont des fonctions et méthodes qui leur sont associées.
liste.append(x)
: ajouter un élément à la fin de la listeliste.pop({index})
: supprimer un élément de la liste à partir de son index (le récupérer en mémoire)liste.remove(x)
: supprimer de la liste la première occurrence de l'élément recherchéliste.index(x)
: renvoyer l'index de la première occurrence de l'élément recherchéliste.count(x)
: compter le nombre d'occurrence de l'élément recherché dans la listeliste.sort()
: trier la liste selon un ensemble de règlesliste_1a4 = [1, 2, 3, 4]
liste_5a8 = [5, 6, 7, 8]
liste_lettres = ['Q', 'Z', 'S', 'D']
# On peut concaténer 2 listes
liste_1a8 = liste_1a4 + liste_5a8
print(liste_1a8)
# Attention .append() n'a pas le même effet
liste_1a8.append(liste_lettres)
print(liste_1a8)
[1, 2, 3, 4, 5, 6, 7, 8] [1, 2, 3, 4, 5, 6, 7, 8, ['Q', 'Z', 'S', 'D']]
🔑 Les dictionnaires sont un type de variable contenant une série de valeurs
associées à des clefs
d'accès.
🔑 Contrairement aux listes, les dictionnaires n'ont pas d'index (ce ne sont pas des itérables).
🔑 Comme les listes, les dictionnaires peuvent contenir plusieurs types de données en même temps, y compris d'autres dictionnaires.
🔑 Un dictionnaire peut contenir plusieurs fois la même valeur mais chaque clef doit être unique.
# créer un dictionnaire
mon_dico_vide = {}
mon_autre_dico_vide = dict()
mon_dico = {"clef" : "valeur"}
print("mon_dico =", mon_dico)
# Ajouter ou modifier des valeurs dans un dictionnaire
print("mon_dico_vide =", mon_dico_vide)
mon_dico_vide["hello"] = "world"
print("mon_dico_vide =", mon_dico_vide)
mon_dico_vide["hello"] = "world!"
print("mon_dico_vide =", mon_dico_vide)
# Supprimer une valeur dans un dictionnaire
del mon_dico_vide["hello"]
print("mon_dico_vide =", mon_dico_vide)
mon_dico = {'clef': 'valeur'} mon_dico_vide = {} mon_dico_vide = {'hello': 'world'} mon_dico_vide = {'hello': 'world!'} mon_dico_vide = {}
# Accéder au contenu d'un dictionnaire
print('mon_dico["clef"] =', mon_dico["clef"])
# Un dictionnaire peut contenir plusieurs types... y compris des dictionnaires
super_dico = {"chiffre": 42, 113: "entier", "clef3" : [1,2,3]}
print('super_dico :', super_dico)
mon_dico["clef"] = valeur super_dico : {'chiffre': 42, 113: 'entier', 'clef3': [1, 2, 3]}
Dans certains cas, utiliser un dictionnaire plutôt qu'une liste permet de naviguer plus facilement entre les données qu'il contient.
identité = ["Berthe", "Morisot", 1865, 1841, 1895]
identité = {"prénom": "Berthe", "nom": "Morisot", "debut": 1865, "naissance": 1841, "mort": 1895}
dico.keys()
: créer un objet itérable contenant la liste des clefs utilisées dans le dictionnairedico.values()
: créer un objet itérable contenant la liste des valeurs contenues dans le dictionnairedico.get()
: envoie la valeur associée à la clef recherchée ou une valeur par défaut si la clef n'existe pasdico.items()
: renvoie le contenu du dictionnaire sous la forme d'une liste de tuples
.dico_demo = {"prénom": "Berthe", "nom": "Morisot", "debut": 1865, "naissance": 1841, "mort": 1895}
# .keys()
print(dico_demo.keys())
print(type(dico_demo.keys()))
for key in dico_demo.keys():
print(key)
dict_keys(['prénom', 'nom', 'debut', 'naissance', 'mort']) <class 'dict_keys'> prénom nom debut naissance mort
# .values()
print(dico_demo.values())
print(type(dico_demo.values()))
for value in dico_demo.values():
print(value)
dict_values(['Berthe', 'Morisot', 1865, 1841, 1895]) <class 'dict_values'> Berthe Morisot 1865 1841 1895
# .get(key, default)
print(dico_demo.get('prénom'))
print(dico_demo.get('métier'))
print(dico_demo.get('métier', 'métier inconnu'))
Berthe None métier inconnu
# .items()
print(dico_demo.items())
print(type(dico_demo.items()))
for duo in dico_demo.items():
print(type(duo), duo, sep=" ; ")
dict_items([('prénom', 'Berthe'), ('nom', 'Morisot'), ('debut', 1865), ('naissance', 1841), ('mort', 1895)]) <class 'dict_items'> <class 'tuple'> ; ('prénom', 'Berthe') <class 'tuple'> ; ('nom', 'Morisot') <class 'tuple'> ; ('debut', 1865) <class 'tuple'> ; ('naissance', 1841) <class 'tuple'> ; ('mort', 1895)
Réaliser les 5 exercices du fichier listes_et_dico.py