On a déjà évoqué que la structure de données élémentaire, dans presque tous les langages de programmation, utilisée pour stocker en ligne des éléments de même nature est le tableau.
Un tableau :
Le type list de Python permet de travailler de cette manière, mais offre en plus les possibilités :
Les méthodes dynamiques utilisent la notation de la programmation orientée objet, avec un . qui indique à gauche le parent et à droite la filiation.
À une liste, on peut ajouter un élément.
>>> une_liste = [2, 3, 5, 7] >>> une_liste.append(11) >>> une_liste [2, 3, 5, 7, 11]
.append() sert à ajouter à la liste citée juste avant le . qui indique la filiation.
Avant la programmation orientée objet, on utilisait une écriture du genre ajoute(élément, ma_liste) ou alors ajoute(ma_liste, élément) ; aucune des deux n'est satisfaisante, et les choses se compliquent lorsqu'on travaille avec des méthodes plus complexes encore...
Voici un programme qui :
mes_carrés,nb_lignes,nb_lignes lignes contenant un entier nombre,nombre lu, ajoute son carré à la liste uniquement s'il est pair.nb_lignes = int(input()) mes_carrés = list() # variante de ma_liste = [] pour une liste vide for _ in range(nb_lignes): nombre = int(input()) carré = nombre * nombre if carré % 2 == 0: mes_carrés.append(carré)
On rappelle qu'on préfère les listes en compréhension avec le code suivant :
nb_lignes = int(input()) ma_liste_lue = [int(input()) for _ in range(nb_lignes)] mes_carrés = [nombre * nombre for nombre in ma_liste_lue if nombre * nombre % 2 == 0]
Cependant, on constate qu'avec les listes en compréhension, on fait deux fois le calcul nombre * nombre pour chaque cas validé ; cela pourrait être gênant et lent, d'autre part le code n'est pas factorisé...
La méthode
.append()est parfois très utile.
ma_liste.sort() trie en place la liste ma_listema_liste.reverse() renverse en place ma_listema_liste.index(élément) renvoie l'indice de élément dans ma_liste ; s'il est absent, une erreur survient.ma_liste.extend(autre_liste) prolonge ma_liste avec autre_listema_liste.remove(élément) enlève élément (le premier trouvé) de ma_listema_liste.insert(élément, indice) ajoute élément à l'indice préciséma_liste.pop() renvoie en supprimant le dernier élément de ma_listePour découvrir toutes les méthodes d'un
objetpython, on utilisedir(objet), et ensuite pour avoir de l'aide sur uneméthodeon entrehelp(objet.méthode)
>>> ma_liste = [2, 3, 5, 7]` >>> dir(ma_liste) ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] >>> help(ma_liste.count) Help on built-in function count: count(value, /) method of builtins.list instance Return number of occurrences of value.
__..count() : renvoie le nombre d'occurrences d'une valeur.More about Python list ; en anglais
Un ensemble (set de type set) est un objet Python muable qui possède des éléments sans doublon, et sans ordre.
i donné.L'utilisation des ensembles ressemble à celle des listes dynamiques, avec des méthodes de programmation orientée objet.
Remarque (hors programme) : il est possible de créer un ensemble figé, donc immuable, avec
frozenset. Ainsi les listes et les ensembles ont leur version immuable : tuple et frozenset.
More about Python set ; en anglais
set() pour un ensemble videset(i*i%10 for i in range(10)) définition en compréhension, ou bien {i*i%10 for i in range(10)}set(ma_liste) pour renvoyer une version sans doublon, ni ordre, d'une liste. La fonction set() essaie de transformer son argument en ensemble.⚠️ l'ensemble vide se définit avec
set(), mais s'affiche comme{}, or définir avec{}donne un dictionnaire vide ; danger, c'est différent.
>>> {n*n%10 for n in range(100)} {0, 1, 4, 5, 6, 9} >>> set("Bonjour") {'r', 'j', 'B', 'u', 'o', 'n'}
Donnons seulement les principales, pour les autres, voir dir(set())
On suppose que truc est un ensemble Python
truc.add(élément) ajoute l'élément à truc, sans doublon, ni ordre.truc.remove(élément) enlève élément à truc ; provoque une erreur si absent.Comme pour les listes, on a les fonctions suivantes pour truc un ensemble (de type set donc) :
len(truc) renvoie le nombre d'éléments de trucx in truc renvoie un booléen, True si x est dans truc, sinon Falsemax(truc) renvoie le maximum de truc s'il est non videmin(truc) renvoie le minimum de truc s'il est non videsum(truc) renvoie la somme des éléments de truc ; erreur si truc contient des éléments non numériques.Le principe d'un dictionnaire est de créer, comme pour un tableau, une association entre des clés et des valeurs.
tab de taille , les clés sont les indices i de inclus à exclus. On note tab[i] la valeur associée à l'indice i.dico, les clés peuvent être tout objet clé, et la valeur associée est référencée avec dico[clé], avec le même style que pour les tableaux, donc.mon_dico = dict()
mon_dico = {}, mais cela peut donner une confusion avec l'ensemble vide...mon_dico[ma_clé] = ma_valeur.# codé en dur longueur_mot = {'pour': 4, 'créer': 5, 'un': 2, 'dictionnaire': 12} # avec une boucle phrase = "pour créer un dictionnaire" longueur_mot = dict() for mot in phase.split(): longueur_mot[mot] = len(mot) # avec une compréhension phrase = "pour créer un dictionnaire" longueur_mot = {mot: len(mot) for mot in phrase.split()}
>>> traduction_fr_en = {'mot': 'word', 'virgule' : 'coma', 'phrase' : 'sentence', 'point': 'point'} >>> traduction_fr_en['phrase'] 'sentence' >>> traduction_fr_en['lettre'] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'lettre'
Voici un script qui enregistre des numéros de cartes pour une classe.
def inscrire_élèves(nb_élèves): num_carte = dict() for _ in range(nb_élèves): nom = input('Quel est votre nom ?') numéro = input('Quel est votre numéro de carte ?') num_carte[nom] = numéro return num_carte
On suppose que l'on a une fonction f dont le calcul coûte cher pour certaines entrées que l'on appelle souvent.
None pour désigner le fait que la fonction n'a pas encore été calculée.Version avec un tableau
# on suppose f est une fonction à un paramètre entier x # On va utiliser un tableau pour stocker certaines valeurs tab_taille = 10000 f_tab = [None for _ in range(tab_taille)] def f_mem(x): if 0 <= x < tab_taille: if f_tab[x] is None: f_tab[x] = f(x) return f_tab[x] else: return f(x)
Version avec un dictionnaire
# on suppose f est une fonction à un paramètre entier x # On va utiliser un dictionnaire pour stocker certaines valeurs f_dico = dict() def f_mem(x): if not(x in f_dico): f_dico[x] = f(x) return f_dico[x]
Le code est bien plus simple, inutile de faire des suppositions sur l'entrée. C'est une excellente pratique. On la trouve souvent avec la dénomination de mémoïsation.
On fera comme s'il n'y avait pas d'ordre pour les clés, et que l'on peut itérer sur les différentes clés d'un dictionnaire avec le code :
for une_clé in mon_dico: ma_fonction(mon_dico[une_clé])