Table des matières

Python : programmation fonctionnelle

Ressources

Présentation

Le paradigme de programmation fonctionnelle se caractérise essentiellement par l'absence d'effets de bord.

Pour cela, le code défini à l'intérieur d'une fonction :

Exemples

a = 0
def augmenter():
    global a
    a = a + 1

Explications :

  • la variable a est définie à l'extérieur de la fonction augmenter() ;
  • Il est précisé dans le corps de la fonction augmenter() que la variable a est définie comme globale ;
  • lors de l'exécution de la fonction augmenter(), la valeur de la variable a est changée pour passer de 0 à 1. Comme il s'agit d'une variable a globale, sa valeur est maintenant changée pour l'ensemble du programme et pas seulement à l'intérieur de la fonction augmenter().
def increment(a):
    return a + 1

Explications :

  • la variable a est passée en paramètre à la fonction augmenter() ;
  • cette fonction retourne la valeur de a augmentée de 1 mais sans modifier la valeur intiale de a qui reste alors à 0.
  • Il n'y a pas d'effet de bord : à l'issue de l'exécution de la fonction augmenter(), la valeur de la variable a n'a pas changée.

Itérer sur des listes

La programmation fonctionnelle est particulièrement intéressant pour intervenir sur des listes. Les exemple qui suivent s'appuie sur la liste de Todos suivantes :

taches = [{"id":"1","libelle":"Préparer mon sac", "accomplie":True},
          {"id":"2","libelle":"Prendre mon petit-déjeuner", "accomplie":False},
          {"id":"3","libelle":"Partir au lycée", "accomplie":False}]

La fonction map

Voici l'utilisation de la fonction map pour avoir une nouvelle liste tachesfinies avec toutes les tâches finies :

# definition de la fonction qui met la valeur True pour la donnée acccomplie 
def fini(tache):
  return {"id":tache["id"],"libelle":tache["libelle"], "accomplie":False}
 
#nouvelle liste avec toutes taches accomplies
tachesfinies = list(map(fini,taches))

Il est possible d'utiliser une fonction anonyme lambda directement dans la fonction map :

# utilisation d'une fonction anonyme lambda
#nouvelle liste avec toutes taches accomplies
tachesfinies = list(map(lambda tache: {"id":tache["id"],"libelle":tache["libelle"], "accomplie":False}, taches))

Les fonctions lambda sont des fonctions anonymes, c'est à dire des fonctions qui n'ont pas de nom. Une fonction anonyme :

  • est définie à l'aide du mot-clef lambda ;
  • les paramètres de la fonction lambda sont définis à gauche du caractère deux-points :
  • le corps de la fonction est défini à sa droite ;
  • le résultat de l'exécution du corps de cette fonction, ce qui correspond à l'instruction return est renvoyé implicitement.

Une fonction anonyme peut être placée :

  • directement dans une fonction qui accepte en paramètre une fonction ;
  • dans une variable pour être utiliser ultérieurement.

Exemple avec une variable :

# definition de la fonction anonyme et affectation dans la variable fois2
fois2 = lambda x: x * 2
 
#utilisation 
>>> print(fois2(4))
>>> 8

Même résultat avec un générateur :

#nouvelle liste avec les taches modifiées pour les indiquer accomplies (finies)
tachesfinies = [fini(tache) for tache in taches]

La fonction filter

Voici l'utilisation de la fonction filter pour avoir une nouvelle liste tachesfinies qui ne contient que les tâches finies :

# definition de la fonction qui teste la valeur True pour la donnée acccomplie 
def fini(tache):
  return tache["accomplie"] == True
 
#nouvelle liste avec uniquement les taches accomplies (finies)
tachesfinies = list(filter(fini,taches))

Même résultat avec une fonction anonyme :

#nouvelle liste avec uniquement les taches accomplies (finies)
tachesfinies = list(filter(lambda tache:tache["accomplie"] == True, taches))

Même résultat avec un générateur :

#nouvelle liste avec uniquement les taches accomplies (finies)
tachesfinies = [tache for tache in taches if tache["accomplie"] == True]

La fonction reduce

La fonction reduce prend en entrée une fonction et une collection d'éléments. Elle renvoie une valeur créée en combinant les éléments de la collection. Exemple qui calcule la somme des éléments d'un tableau

# importation de la fonction reduce
from functools import reduce
 
tableau = [0, 1, 2, 3, 4]
 
somme = reduce(lambda a, x: a + x, tableau)
# somme contient 10

Explications :

  • x est l'élément courant de l'itération et a est l'accumulateur ;
  • l'accumulateur est la valeur renvoyée par l'exécution de la fonction lambda sur l'élément précédent ;
  • la fonction reduce() parcourt les éléments de la liste et, pour chacun d'eux, exécute la fonction lambda sur les valeurs courantes de a et de x et renvoie le résultat qui devient le a de l'itération suivante ;
  • la valeur de a lors de la première itération est la première valeur de la liste ; la première valeur de x est donc le second élément de la liste.
  • pour préciser une valeur initiale différente de a, on le précise en 3ème paramètre de la fonction reduce :
somme = reduce(lambda a, x: a + x, tableau, 50)

Trier des listes

taches.sort(key=lambda tache: tache["id"], reverse=True)

Retour au cours : Les instructions du langage Python