Aller au contenu

Exemples à savoir programmer

Parcourir une liste, un dictionnaire

Parcours par indice d'une liste :

for i in range(len(ma_liste)): # (1)
    print(ma_liste[i]) # (2)
  1. on peut bien sûr créer une variable taille = len(ma_liste) avant et ensuite utiliser range(taille)
  2. ou faire n'importe quoi d'autre avec ma_liste[i]

Parcours par valeur d'une liste :

for v in ma_liste: # (1)
    print(v)
  1. On fera attention à ne pas appeler i les valeurs parcourues ainsi, ça prête à confusion. On a mis v ici mais on préfère un nom explicite : sommet si ce sont des sommets d'un graphe, nom si c'est une liste de noms, etc.

Parcours d'un dictionnaire :

for cle in mon_dico:
    print(cle, mon_dico[cle]) # (1)
  1. cle parcourt l'ensemble des clés du dictionnaire, et on accède aux valeurs avec mondico[cle]. On peut aussi modifier les valeurs avec mondico[cle] = nouvelle_valeur

Utiliser une variable dans un parcours

Pour compter quelque chose:

somme = 0
for v in ma_liste:
    somme = somme + v

Pour marquer dans une variable booléenne un résultat:

tous_superieur_10 = True
for v in ma_liste:
    if v <= 10:
        tous_superieur_10 = False

Ou pour trouver un minimum/maximum/etc et sa position:

valeur_minimum = ma_liste[0] # (1)
position_minimum = 0
for i in range(len(ma_liste)): # (2)
    if ma_liste[i] < valeur_minimum:
        valeur_minimum = ma_liste[i]
        position_minimum = i

  1. On peut ne retenir que la position si on veut (à vous de faire l'exercice).

    Et on fait attention à l'initialiser avec la première valeur plutôt qu'avec 0 parce que si toutes les valeurs sont supérieures à 0 le résultat serait faux (il faut mettre une valeur initiale dont on est sûr qu'elle n'est pas plus petite que le vrai minimum).

  2. On ne peut pas faire un parcours par valeur ici car on pourrait trouver le minimum mais on n'aurait pas accès à sa position.

    On pourrait aussi utiliser range(1, len(ma_liste)) car la position 0 est déjà prise en compte par l'initialisation.

Faire une fonction qui parcourt une liste et la tester

def position_minimum(liste): # (3)
    pos_min = 0
    for i in range(len(liste)):
        if liste[i] < liste[pos_min]:
            pos_min = i
    return pos_min

print(position_minimum([2,1,3])) # (1)

assert position_minimum([2,1,3]) == 1 # (2)
  1. Si on veut afficher ce que renvoie la fonction pour débugguer
  2. Si on veut montrer qu'un test est valide (silencieux si ça marche, provoque une erreur sinon)
  3. Attention si ce n'est pas clair pour vous : les paramètres quand on définit une fonction sont des paramètres formels, c'est à dire des noms de nouvelles variables qu'on choisit, et qui seront des variables locales à la fonction.

    La valeur qu'ils prendront sera celle de l'argument donné à l'appel de la fonction, qui peut être différente à chaque appel.

    Donc dans le code de la fonction, c'est une variable et on ne peut pas savoir exactement quelle valeur sera dedans.

Créer une classe (programmation orientée objet)

class Arbre: # (1)
    def __init__(self): # (2)
        self.sous_arbres = [] # (3)

    def taille(self):
        resultat = 1 # (4)
        for arbre in self.sous_arbres:
            resultat += arbre.taille() # (5)
        return resultat

    def ajoute(self, arbre):
        """ajoute arbre comme sous-arbre"""
        self.sous_arbres.append(arbre)
  1. Par convention en python, les noms des classes commencent par des majuscules et les autres variables par des minuscules.

  2. On ajoute toujours self comme paramètre aux méthodes d'une classe, mais on ne le donne pas quand on appelle la méthode. Si l'objet s'appelle a par exemple, on appellera a.taille() car c'est a lui même qui remplacera la variable self.

    self est donc un mot-clé qui fait référence à l'objet sur lequel on a appelé une méthode, car il peut bien sûr exister plusieurs objets de la même classe. On ne l'utilise qu'à l'intérieur du code de la classe, jamais en dehors.

  3. C'est un attribut car on l'a créé avec self., donc on il sera stocké dans l'objet et on pourra y accéder depuis les autres méthodes ou avec nom_de_l_objet.nom_de_l_attribut.

    Comme on veut le créer vide, on ne l'a pas mis dans les paramètres de __init__ et on créera un objet avec l'appel à Arbre().

    Si on voulait donner la liste des sous-arbres à la création, on aurait pu l'ajouter en paramètre et écrire self.sous_arbres = sous_arbres et dans ce cas on créerait un objet avec Arbre([a1,a2,a3]) par exemple si a1,a2,a3 sont des objets de type Arbre.

  4. Ici resultat est une variable locale à la méthode et non un attribut. On fait ce choix si on n'a pas besoin de stocker ce résultat dans l'objet et qu'on en a juste besoin le temps que la méthode s'exécute.

  5. Cette méthode est récursive parce qu'on l'appelle sur chacun des sous-arbres. Il n'y a pas de cas de base explicite mais elle s'arrêtera sur les arbres qui n'ont pas de sous-arbres (on aura alors un parcours sur une liste vide, qui ne fera donc pas d'appel récursif).

    Cette méthode effectue en fait un parcours en profondeur sur l'arbre de départ.