5.4. Les valeurs de retour

Les fonctions construites jusqu’ici sont plutôt limitées car aucune valeur ne peut en sortir (à moins de la stocker dans une variable déclarée en dehors de la fonction, ce qui est une mauvaise pratique). Elles peuvent afficher un résultat dans la console, par exemple, mais ne peuvent pas vraiment être utilisées pour obtenir des résultats intermédiaires qui pourraient notamment être utilisés comme valeurs d’entrée pour d’autres fonctions.

5.4.1. Renvoyer une valeur

Pour illustrer le principe des valeurs de retour, essayons de créer une fonction qui transforme une séquence d’ADN constituée des bases A, T, C et G en sa séquence complémentaire. Tous les A sont donc transformés en T, les T en A, les C en G et les G en C :

  • A → T

  • T → A

  • C → G

  • G → C

La fonction prend en paramètre une chaîne de caractères contenant la séquence de départ, par exemple "ATCCAGATCAAGTCTTGA". Elle crée une deuxième chaîne de caractères contenant la séquence complémentaire (ici, "TAGGTCTAGTTCAGAACT") et l’affiche dans la console.

def find_complement(seq):      # le paramètre contiendra la séquence d'ADN fournie en entrée
    compl_seq = ""            # on crée une chaîne vide pour la séquence complémentaire
    for base in seq:          # on itère sur la séquence en parcourant les bases une à une
        if base == 'A':       # si la base en question est A...
            compl_seq += 'T'  # on ajoute T à la séquence complémentaire
        elif base == 'T':     # sinon, si la base est T...
            compl_seq += 'A'  # on ajoute A à la séquence complémentaire
        elif base == 'C':     # et ainsi de suite...
            compl_seq += 'G'
        elif base == 'G':
            compl_seq += 'C'
        else:                 # sinon, il y a une erreur dans la séquence fournie
            print("La séquence contient une base erronée : " + base)
    print(compl_seq)          # on affiche la séquence complémentaire


find_complement("ATCCAGATCAAGTCTTGA")  # on appelle la fonction
TAGGTCTAGTTCAGAACT

Le programme fonctionne correctement mais l’utilité de notre fonction est limitée. En effet, on est obligé d’afficher la séquence complémentaire produite dans la console, ce qui n’est pas très utile et nous empêche de l’utiliser plus tard dans notre programme pour un autre but. C’est ici qu’interviennent les valeurs de retour des fonctions.

On va modifier notre fonction pour lui demander de renvoyer la séquence complémentaire grâce au mot réservé return, suivi de la valeur à renvoyer. Il est alors possible d’assigner la valeur de retour de la fonction à une variable au moment où on l’appelle. Notez que le programme sort de la fonction au moment où l’instruction return s’exécute, ce qui est aussi un moyen pratique d’interrompre une fonction au besoin.

def find_complement(seq):
    compl_seq = ""
    for base in seq:
        if base == 'A':
            compl_seq += 'T'
        elif base == 'T':
            compl_seq += 'A'
        elif base == 'C':
            compl_seq += 'G'
        elif base == 'G':
            compl_seq += 'C'
        else:
            print("La séquence contient une base erronée : " + base)
    return compl_seq


seq_c = find_complement("ATCCAGATCAAGTCTTGA")       # on stocke la valeur de retour
seq_o = find_complement(seq_c)                      # on retrouve la séquence originale
print("La séquence originale est      : " + seq_o)  # on affiche les résultats
print("La séquence complémentaire est : " + seq_c)
La séquence originale est      : ATCCAGATCAAGTCTTGA
La séquence complémentaire est : TAGGTCTAGTTCAGAACT

Note

Les fonctions sans valeur de retour sont généralement appelées des procédures.

5.4.2. Renvoyer plusieurs valeurs

Il est possible de renvoyer plusieurs valeurs depuis une fonction. Pour cela on utilise les tuples, comme dans l’exemple ci-dessous qui recherche les valeurs minimale et maximale d’une liste de nombres.

def min_and_max(numbers):
    min = max = numbers[0]  # on initialise `min` et `max` avec le 1er élément de la liste
    for n in numbers[1:]:   # on parcourt le reste de la liste
        if n < min:
            min = n         # nouveau minimum
        elif n > max:
            max = n         # nouveau maximum
    return min, max         # on renvoie les deux valeurs dans un tuple
>>> print(min_and_max([0, 3, -1, 8, 5]))
(-1, 8)
>>> type(min_and_max([0, 3, -1, 8, 5]))
<class 'tuple'>
>>> min, max = min_and_max([0, 3, -1, 8, 5])
>>> print(min)
-1
>>> print(max)
8

5.4.3. Nombre arbitraire de paramètres

Les fonctions mathématiques sont de bons exemples de fonctions avec valeur de retour. Essayons d’écrire une simple fonction add() qui calcule la somme de tous les nombres reçus en paramètre. Or, on ne sait pas à l’avance combien de valeurs la fonction va recevoir et, par conséquent, combien de paramètres déclarer. Une solution serait de déclarer un seul paramètre, une liste, contenant tous les nombres à additionner.

def add(numbers):
  total = 0
  for n in numbers: # pour chaque nombre parmi les nombres...
    total += n      # on l'ajoute à la somme
  return total      # on renvoie la somme


print(add([2, 61, 10, -32, 9]))
50

Notre programme fonctionne comme souhaité, mais Python nous offre une option plus pratique. On peut indiquer à add() qu’elle attend un nombre arbitraire de paramètres en précédant le dernier d’un astérisque *. Ce paramètre sera alors un tuple contenant tous les paramètres reçus.

def add(*numbers):  # le paramètre est un tuple contenant toutes les valeurs reçues
  total = 0
  for n in numbers:  # les tuples se comportent comme les listes pour l'itération
    total += n
  return total


print(add(2, 61, 10, -32, 9))  # on donne directement les nombres en paramètre (sans []) 
50