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
return
permet 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