Jusqu'ici, on a vu des fonctions qui prennent en argument des nombres ou des listes, comme :
def f(x):
return 2 * x
En Python, on peut passer une fonction en paramètre d'une autre fonction. Par exemple :
def applique_deux_fois(fct, a):
tmp = fct(a)
return fct(tmp)
Ici fct
est un paramètre de applique_deux_fois
de type fonction. Pour passer f
comme paramètre effectif de fct
, on écrit simplement :
applique_deux_fois(f, 4)
On a bien f(f(4)) == 16
.
Une fonction qui prend en paramètre ou renvoit une fonction est dite d'ordre supérieur. f
est d'ordre 1, applique_deux_fois
est d'ordre 2.
Bien sûr, comme pour les fonctions d'ordre 1, le paramètre effectif (celui passé au moment de l'appel) peut avoir le même nom que le paramètre formel (celui de la définition) :
def applique_trois_fois(f, x):
tmp1 = f(x)
tmp2 = f(tmp1)
tmp3 = f(tmp2)
return tmp3
applique_trois_fois(f, 2)
import math
applique_trois_fois(math.sin, 2)
math.sin(math.sin(math.sin(2)))
On définit la fonction applique_partout
qui applique une fonction à chaque élément d'une liste :
def applique_partout(f, lst):
res = []
for e in lst:
res.append(f(e))
return res
x = [1, 2, 10]
applique_partout(f, x)
En fait, cette fonction existe déjà en Python, elle s'appelle map
:
map(f, x)
En Python, on a aussi une autre syntaxe, souvent plus jolie, pour map
:
[f(a) for a in x]
On peut affecter une fonction à une variable comme avec les autres valeurs :
ma_fonction = f
ma_fonction(4)
Quand on définit une fonction avec
def f(x):
return x * 2
on fait deux choses : on crée l'objet « fonction qui a x
associe x + 1
», et l'affecte à une variable (globale) f
.
On peut aussi créer une fonction sans lui donner de nom : c'est une fonction lambda :
f(3)
(lambda x: x * 2)(3)
(lambda x: x * 2)
se lit « Fonction qui a x
associe x * 2
» (Parfois notée $x \mapsto 2x$ chez les mathématiciens)
g = lambda x: x * 2 # équivalent à def g(x): return x * 2, mais plus court.
g(3)
Les fonctions lambda sont surtout utiles pour passer une fonction en paramètre à une autre :
map(lambda x: x + 1, [1, 3, 42])
Une fonction lambda peut avoir plusieurs paramètres :
somme = lambda x, y: x + y
somme(10, 3)
Pour éviter la tentation de code illisible, Python limite les fonctions lambda :
Une seule ligne
return
implicite
Si on veut écrire des choses plus compliquées, on utilise def
(on peut toujours).
Même avec ces limitations, on peut souvent s'en sortir. Par exemple :
def abs_avec_def(x):
if x >= 0:
return x
else:
return -x
map(abs_avec_def, [-1, 0, 42])
map(lambda x: x if x >= 0 else -x, [-1, 0, 42])