Tableaux et matrices

information-icon

Les premières épreuves du bac de français édition 2024 sont pour bientôt ! Consulte les dates du bac de français, notre programme de révision accompagné de toutes nos fiches de révisions pour te préparer au mieux à ton examen 💪

Introduction :

Dans ce cours nous allons étudier les principales structures de données, également appelées types construits. Ces structures sont destinées à regrouper et à manipuler des ensembles de données. Nous étudierons successivement les p-uplets ou tuples, puis les tableaux appelés listes et enfin les dictionnaires.

Tuples

Commençons par étudier la structure de données de type tuple ou p-uplet.

  • En mathématiques un p-uplet est un ensemble d'éléments ordonnés de p éléments, p étant un entier naturel non nul. Cet ensemble est parfois noté n-uplet ou encore tuple, ce dernier terme étant d'origine anglo-saxonne.

Le concept de n-uplet a été implémenté dans le langage Python sous le nom de tuple.

bannière definition

Définition

Tuple :

Un tuple est une séquence ordonnée et finie d'éléments.

Création de tuples

La déclaration d'un tuple s'effectue par énumération des éléments séparés par une virgule.

animaux = ('chien', 'chat', 'oiseau')

tirage_loterie = (3, 17, 21, 33, 41, 44, 49)

Un tuple peut aussi contenir des éléments hétérogènes.

melange = ('hello tuple', 12, True, [4, 7, 9])

L'emploi des parenthèses est optionnel pour la création d'un tuple, sauf dans deux cas particuliers :

  • la création d'un tuple vide ;
  • la création d'un tuple contenant un seul élément.

tuple_vide = ()

tuple_mono_element = (12,)

  • La déclaration d'un tuple contenant un seul élément nécessite l'ajout d'une virgule pour ne pas être confondu avec une déclaration de variable non composée telle qu'un nombre ou une chaîne de caractères.

Itération sur les tuples

L'itération sur les tuples s'effectue avec la construction for … in .

tirage_loterie = (3, 17, 21, 33, 41, 44, 49)

for numero in tirage_loterie:

print(numero)

Produit l'affichage suivant :

3
17
21
33
41
44
49

Accès aux éléments d'un tuple

Les éléments individuels d'un tuple sont accessibles avec la notation indicielle.

animaux = ('chien', 'chat', 'oiseau')

print(animaux[0])

# affiche chien

print(animaux[2])

# affiche oiseau

bannière attention

Attention

L’indice du premier élément d’un tuple est $0$ et non $1$. Il en est de même pour le premier élément d’une liste.

Immutabilité des tuples

Les tuples sont immutables. Il n'est donc pas possible d'ajouter ou de supprimer un élément composant le tuple.

bannière attention

Attention

Il n'est pas non plus possible de modifier un élément du tuple. Python génère une erreur si on tente une telle assignation.

Par exemple, animaux[1] = 'souris' déclenche l'affichage d'une erreur.

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

TypeError: 'tuple' object does not support item assignment

Tuples et retours multiples dans une fonction

En Python, une fonction peut retourner simultanément plusieurs valeurs, constituant un tuple.

def minuscules_majuscules(chaine):

"""Retourne les variantes minuscules et majuscules d’une chaîne de caractères"""

chaine_en_minuscules = chaine.lower()

chaine_en_majuscules = chaine.upper()

return chaine_en_minuscules, chaine_en_majuscules

On demande l'affichage d'un appel de cette fonction.

print(minuscules_majuscules("Ada Lovelace"))

# affiche ('ada lovelace', 'ADA LOVELACE')

Nous pouvons assigner le résultat de cette fonction à une variable.

resultat = minuscules_majuscules("Ada Lovelace")

Demandons à Python d'afficher le type de variable.

print(type(resultat))

# affiche <class 'tuple'>

Il s'agit bien d'un tuple. Nous pouvons également effectuer des assignations multiples à partir d'un tuple.

minuscules, majuscules = resultat

print(minuscules)

# affiche ada lovelace

Le type de la variable « minuscules » est celui du premier élément composant le tuple. Dans le cas présent c'est une chaîne de caractères.

print(type(minuscules))

# affiche <class 'str'>

Le tuple accepte de contenir des éléments hétérogènes. Nous pouvons les employer pour stocker des données de différents types.

Le tuple n'indique cependant pas quelle donnée est stockée à quel emplacement. Il existe une solution pour pallier cette limitation des tuples classiques : l'emploi de tuples nommés.

Tuples nommés

Les tuples nommés conservent les caractéristiques des tuples classiques mais apportent le bénéfice de pouvoir nommer les attributs composant le tuple.

bannière definition

Définition

Tuples nommés :

Les tuples nommés sont une sous-classe des tuples dont les valeurs sont nommées.

Le module « collections » de la bibliothèque standard de Python propose une classe d'objets tuples nommés, mobilisables par un simple import.

from collections import namedtuple

On définit un nouveau type de tuple nommé en déclarant :

  • son nom ;
  • la liste des noms de ses attributs.

Eleve = namedtuple('Eleve', ['prenom', 'age', 'taille'])

On peut ensuite créer des tuples nommés d'élèves avec les caractéristiques choisies, avec ou sans le recours au nom des attributs.

alice = Eleve('Alice', 18, 165)

paul = Eleve(prenom='Paul', age=17, taille=175)

On peut noter que dans le cas du recours au nom des attributs, l’ordre d’affectation n’est pas imposé. Ainsi, on aurait pu définir la variable « paul » de cette manière :

paul = Eleve(prenom='Paul', taille=175, age=17)

L'affichage de la variable "alice" propose le tuple nommé au complet c’est-à-dire les noms des attributs accompagné des valeurs qui y sont rattachées.

print(alice)

# affiche Eleve(prenom='Alice', age=18, taille=165)

L'autre intérêt du tuple nommé est de pouvoir accéder aux attributs par leur nom.

print(alice.prenom)

# affiche 'Alice'

print(paul.age)

# affiche 17

Les tuples et les tuples nommés sont des conteneurs immutables pouvant réunir des éléments hétérogènes. L'absence de mutabilité peut s'avérer problématique dans certains cas.

Intéressons-nous maintenant à des structures de données mutables : d'abord les listes puis les dictionnaires.

Listes

Les tableaux, appelés listes en Python, sont des structures de données mutables. Ce sont également des structures de données ordonnées. Ces deux caractéristiques les rendent très utiles pour de nombreux usages.

bannière definition

Définition

Listes :

Les listes sont des structures de données ordonnées et mutables.

Création de listes

La création de liste s'effectue par énumération des éléments composant la liste.

prenoms = ['Alice', 'Charles', 'Paul']

nombres = [-44, 31, 12, 0, 4, -7, 99, 15]

Itération sur les listes

L'itération sur les listes s'effectue avec la construction for … in .

for prenom in prenoms:

print(prenom)

Produit l'affichage suivant :

$\text{Alice}$
$\text{Charles}$
$\text{Paul}$

Elle peut également être effectuée avec la notation indicielle.

Accès aux des éléments d'une liste

La notation indicielle permet l'accès aux éléments individuels d'une liste.

print(prenoms[1])

# affiche Charles

Modification d'un élément d'une liste

Le caractère mutable des listes permet d'en modifier les éléments.

prenoms[1] = 'Guido'

print(prenoms)

# affiche ['Alice', 'Guido', 'Paul']

Suppression d'un élément d'une liste

La suppression d'un élément s'effectue avec l'instruction del .

del(prenoms[1])

print(prenoms)

# affiche ['Alice', 'Paul']

Ajout d'un élément à la fin d’une liste

L'ajout d'un élément à la fin d’une liste s'effectue avec l'instruction append.

prenoms.append('Alan')

print(prenoms)

# affiche ['Alice', 'Paul', 'Alan']

Listes imbriquées

Les listes peuvent être composées de listes. Il est ainsi possible de créer et de manipuler des listes imbriquées.
Créons une matrice en imbriquant des listes.

matrice = [[0, 4, 2], [1, 7, -1], [2, 0, 3]]

Pour une meilleure lisibilité, il est également possible d'employer cette présentation.

matrice = [[0, 4, 2],

[1, 7, -1],

[2, 0, 3]]

L'accès aux éléments individuels est possible de manière indicielle. On précise la position dans le premier niveau de liste, puis celle dans la liste imbriquée.

bannière exemple

Exemple

# Accès au troisième élément de la seconde ligne :

print(matrice[1][2])

# affiche -1

Nous avons abordé les principales manipulations avec les listes. Il existe toutefois une autre manière de composer des listes, par compréhension.

Listes en compréhension

Nous consacrons une partie spécifique aux listes en compréhension. Il s'agit de listes en tous points identiques à celles que nous venons d'étudier, mais que nous construisons d'une manière différente. Illustrons cela avec un exemple.

bannière exemple

Exemple

Nous souhaitons générer la liste des nombres pairs inférieurs ou égaux à dix. Commençons de manière classique en effectuant une boucle et en utilisant un test conditionnel.

nombres_pairs = []

for n in range(11):

if n % 2 == 0:

nombres_pairs.append(n)

Vérifions que notre programme fonctionne bien.

print(nombres_pairs)

# affiche [0, 2, 4, 6, 8, 10]

La création de liste en compréhension permet d'obtenir le même résultat avec un code beaucoup plus compact puisqu'il tient en une seule ligne.

nombres_pairs = [n for n in range(11) if n % 2 == 0]

Vérifions le résultat obtenu :

print(nombres_pairs)

# affiche [0, 2, 4, 6, 8, 10]

bannière à retenir

À retenir

Une liste en compréhension se génère entre crochets. Elle inclut une expression suivie d'au moins une clause for et optionnellement d'autres clauses for ou if .

Filtrage conditionnel

Le filtrage conditionnel est tout à fait possible en compréhension de liste.

bannière exemple

Exemple

prenoms = ['Alice', 'Bob', 'Caroline', 'Paul', 'Zoe']

prenoms_longs = [prenom for prenom in prenoms if len(prenom) > 3]

print(prenoms_longs)

# affiche ['Alice', 'Caroline', 'Paul']

Il est également possible d'appliquer des conditions multiples ou des choix alternatifs. Dans ce cas, la partie conditionnelle doit être placée avant la boucle for.

bannière exemple

Exemple

  • Si un prénom ne comporte pas le caractère « o » il est remplacé par « Anonyme ».

certains_prenoms = [prenom if 'o' in prenom else 'Anonyme' for prenom in prenoms]

print(certains_prenoms)

# affiche ['Anonyme', 'Bob', 'Caroline', 'Anonyme', 'Zoe']

$$

  • Sélection des prénoms courts comportant le caractère « o ».

prenoms_courts_en_o = [prenom for prenom in prenoms if len(prenom) < 4 and 'o' in prenom]

print(prenoms_courts_en_o)

# affiche ['Bob', 'Zoe']

Il est possible d'écrire une liste par compréhension sur plusieurs lignes pour mieux en distinguer les composantes.

prenoms_courts_en_o = [

prenom

for prenom in prenoms

if len(prenom) < 4 and 'o' in prenom]

Expressions complexes

Les expressions au cœur de l'itération des listes en compréhension peuvent être complexes et faire appel à des fonctions.

racines_carrees_arrondies_majorees = [round(nombre ** 0.5, 2) + 1 for nombre in range(10)]

print(racines_carrees_arrondies_majorees)

# affiche [1.0, 2.0, 2.41, 2.73, 3.0, 3.24, 3.45, 3.65, 3.83, 4.0]

Imbrication de listes en compréhensions

formes = ['carré', 'cercle', 'triangle', 'rectangle']

couleurs = ['rouge', 'vert', 'bleu']

formes_colorees = [forme + ' ' + couleur for forme in formes for couleur in couleurs]

print(formes_colorees)

# affiche ['carré rouge', 'carré vert', 'carré bleu', 'cercle rouge', 'cercle vert', 'cercle bleu', 'triangle rouge', 'triangle vert', 'triangle bleu', 'rectangle rouge', 'rectangle vert', 'rectangle bleu']

bannière à retenir

À retenir

L'ordre des boucles est celui qui serait utilisé pour générer la liste sans compréhension. La boucle extérieure s'écrit donc avant la boucle intérieure dans la compréhension de liste.

Transposition de matrice

bannière definition

Définition

Une matrice :

Une matrice, en mathématiques, est un tableau de nombres qui permet de traiter globalement un ensemble de calculs identiques.
Une matrice de format ou dimension $(n ; p)$ est un tableau rectangulaire de nombres comportant $n$ lignes et $p$ colonnes. Ces nombres sont appelés les coefficients ou les termes de la matrice.

La matrice transposée d’une matrice $\text{A}$ de format $(n ; p)$ est la matrice de format $(p ; n)$, noté $\text{A}^{\text{T}}$, obtenue en échangeant les lignes et les colonnes de $\text{A}$.

La formulation par compréhension de listes nous permet de réaliser une transposition de matrice avec un code compact.

matrice = [[0, 4, 2], [1, 7, -1], [2, 0, 3]]

transpo = [[ligne[i] for ligne in matrice] for i in range(len(matrice))]

Vérifions le résultat obtenu.

print(transpo)

# affiche [[0, 1, 2], [4, 7, 0], [2, -1, 3]]

Vous pouvez noter au passage que la longueur d’une liste est donnée par la fonction len, comme pour la longueur d’une chaîne de caractères, d’un tuple ou d’un dictionnaire. Le code équivalent sans compréhension de liste est plus long et sa lisibilité n'est pas meilleure.

transpo = []

for i in range(len(matrice)):

rangee = []

for ligne in matrice:

rangee.append(ligne[i])

transpo.append(rangee)

Les listes par compréhension offrent d'intéressants raccourcis syntaxiques pour la génération et le traitement de listes. Elles sont à la fois d'une plus grande compacité et restent bien lisibles avec une syntaxe proche du langage naturel.

Dictionnaires

Les dictionnaires ressemblent aux listes par certains aspects, mais diffèrent par d'autres. Ainsi, les listes sont indexées par des nombres, tandis que les dictionnaires ont recours à des clés nommées, qui ne sont pas nécessairement des nombres. Dans d'autres langages, les dictionnaires sont appelés tableaux associatifs. Comme les listes, les dictionnaires sont mutables.

bannière definition

Définition

Dictionnaires :

Les dictionnaires sont des ensembles mutables, non ordonnés, de paires composées d'une clé et d'une valeur en correspondance.

La manipulation des dictionnaires présente de nombreuses similitudes avec celles des tuples et des listes étudiés précédemment.

Création d'un dictionnaire

La création d'un dictionnaire s'effectue par énumération des paires de clés et de valeurs associées, le tout étant encadré par des accolades.

alice = {'prenom': 'Alice', 'taille': 165, 'age': 18, 'permis': True}

Comme pour les listes, il est possible de présenter ce code sur plusieurs lignes pour mieux identifier les paires clé-valeur composant le dictionnaire.

alice = {

'prenom': 'Alice',

'taille': 165,

'age': 18,

}

Accès aux éléments d'un dictionnaire

La consultation du dictionnaire avec une clé permet d'obtenir la valeur correspondante.

print(alice['age'])

# affiche 18

Si la clé n'existe pas, une erreur survient.

print(alice['poids'])

# affiche KeyError: 'poids'

Ajout d'éléments

L'ajout de nouveaux éléments s'effectue par affectation d'une valeur à une nouvelle clé.

alice['poids'] = 60

Modification d'un élément

Si la clé existe déjà, une nouvelle affectation de valeur remplace l'ancienne.

alice['poids'] = 58

Suppression d'éléments

La suppression de l’élément d’un dictionnaire s'effectue, comme pour les listes, avec l'instruction del.

del(alice['poids'])

Si on tente de supprimer une clé inexistante, une erreur survient.

del(alice['imc'])

# affiche KeyError: 'imc'

Itérations sur les dictionnaires

Les itérations sur les dictionnaires peuvent porter sur les clés, sur les valeurs, ou sur les deux en même temps.

Pour le découvrir prenons comme exemple celui des métadonnées accompagnant une image.

exif = {

"Shutter Speed": "1/50 sec",

"Aperture Value": "f/2.1",

"ISO Speed Ratings": "1600",

"Focal Length": "50 mm",

"Lens": "50.0 mm »

}

Voyons dans un premier temps l'itération sur les clés.

for element in exif.keys():

print(element)

Produit l'affichage suivant :

Shutter Speed

Aperture Value

ISO Speed Ratings

Focal Length

Lens

  • Seules les clés sont affichées.

Voyons maintenant l'itération sur les valeurs.

for element in exif.values():

print(element)

Produit l'affichage suivant :

1/50 sec

f/2.1

1600

50 mm

50.0 mm

  • Les valeurs sont affichées, mais pas les clés.

L'itération simultanée sur les clés et les valeurs s'effectue ainsi :

for cle, valeur in exif.items():

print(cle, valeur)

Produit l'affichage suivant :

Shutter Speed 1/50 sec

Aperture Value f/2.1

ISO Speed Ratings 1600

Focal Length 50 mm

Lens 50.0 mm

L’usage de paires clé-valeur étant très répandu, les dictionnaires sont des structures de données fréquemment employées dans les développements informatiques.

Conclusion :

Les tuples, les listes et les dictionnaires sont des structures de données distinctes, dotées chacune de caractéristiques propres : les tuples sont ordonnés et non mutables, les listes sont ordonnées et mutables et les dictionnaires sont non-ordonnés et mutables. Les tuples peuvent être nommées, se rapprochant ainsi du principe des clés du dictionnaire, alors que les listes ne peuvent pas être nommées.

Le choix d'une structure de donnée dépend des besoins et des usages souhaités. On s'interrogera notamment sur la nécessité ou non de disposer de structures mutables ou ordonnées et sur la manière dont on souhaite y accéder.