3.3. Les fonctions def#
Evidemment, même si la fonction peut s’écrire sur une seule ligne, il est possible d’utiliser def plutôt qu’une lambda-fonction. Nous reprenons donc les exemples précédents avec cette nouvelle syntaxe.
Important
A nouveau l’indentation est synthaxique donc obligatoire.
La fonction peut prendre autant d’arguments que nécessaire (cela peut être 0 ou bien n’importe quel entier aussi grand que voulu - il n’y a plus de limites depuis python 3.6).
Le mot-clef
returnpermet d’indiquer le (les) résultat(s) que renvoie la fonction. Elle s’arrête aussitôt après, même s’il reste des instructions. La fonction peut n’avoir aucunreturn, c’est-à-dire ne renvoyer aucune valeur : on peut dans ce cas l’appeler procédure.
def carre(x):
return x**2
x = 2
print(f"Evaluation de la fonction carre sur x={x} : {carre(x)}")
Evaluation de la fonction carre sur x=2 : 4
def echange(x, y):
return y, x
x, y = 1, 2
z, t = echange(x, y)
print(f"On échange {x} et {y} : {z}, {t}")
On échange 1 et 2 : 2, 1
def inverse(x):
if x == 0:
return None
return 1./x
x, y = 2, 0
print(f"1/{x} = {inverse(x)}")
print(f"1/{y} = {inverse(y)}")
1/2 = 0.5
1/0 = None
Notez dans le dernier exemple ci-dessous qu’il y a deux return. Si le test x == 0 est vrai alors le premier return est utilisé : la fonction retourne None et s’arrête. Si le test est faux alors la fonction descend au deuxième return.
Il est également possible d’utiliser les fonctions de manière récursive. Par exemple pour calculer \(n!\).
def factorielle(n):
if n != int(n):
print(f"{n} n'est pas un entier !")
return
if n <= 0:
print(f"{n} est négatif !")
return
if n == 1:
return 1
return n * factorielle(n-1)
print(factorielle(17.1))
print(factorielle(-3))
print(factorielle(3))
print(factorielle(100))
17.1 n'est pas un entier !
None
-3 est négatif !
None
6
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
Exercice
Proposez une fonction récursive mon_pgcd qui calcule le pgcd de 2 entiers à l’aide de l’algorithme d’Euclide :
si \(b = 0, PGCD(a, b) = \vert a \vert\),
si \(b \neq 0\), \(PGCD(a, b) = PGCD(b, r)\), où \(r\) est le reste de la division euclidienne de \(a\) par \(b\).
Solution récursive
Show code cell source
def mon_pgcd(a, b):
if type(a) != int or type(b) != int:
print(f"Dans mon_pgcd a={a} et b={b} doivent être entiers")
return
if b == 0:
return abs(a)
return mon_pgcd(b, a % b)
a, b = 153*17, 153*15
print(f"Le PGCD de {a} et de {b} vaut {mon_pgcd(a, b)}")
Le PGCD de 2601 et de 2295 vaut 153
Solution itérative
Show code cell source
def mon_pgcd(a, b):
if type(a) != int or type(b) != int:
print(f"Dans mon_pgcd a={a} et b={b} doivent être entiers")
return
while b != 0:
a, b = b, a % b
return abs(a)
a, b = 153*17, 153*15
print(f"Le PGCD de {a} et de {b} vaut {mon_pgcd(a, b)}")
Le PGCD de 2601 et de 2295 vaut 153