Outils pour utilisateurs

Outils du site


nsi:langages:python:tableaux

Tableaux

Notion de tableau

Imaginons la mémoire comme une grille. Chaque case contient a une adresse et contient une valeur.

Exemple : la case mémoire d'adresse 13 contient la valeur 17.

La variable x est associée à l'adresse 28 et x = 96.

Un tableau consiste à réserver plusieurs cases consécutives.

Exemple : le tableau t pointe sur l'adresse 16 qui est la première case d'un tableau occupant 4 cases.

t = [3, 4, 13, 48]

On sait ou commence t. On voit qu'il est facile de :

  • trouver par ex. le 2e élément de t
  • modifier par ex. le 2e élément de t

Mais il est plus pénible d'essayer d'insérer un nouvel élément au milieu du tableau.

Donc, Normalement, dans les différents langages, *pour pouvoir réserver la place nécessaire dans la mémoire*

  • un tableau doit contenir un nombre constant d'éléments, connu lors de la création
  • les éléments du tableau doivent tous être de même type. Ce type doit être connu à la création.
Pour se faire une idée : en Python un entier occupe 4 octets, un flottant (nombre à virgule) en occupe 8. Si on remplit notre tableau avec des flottant ou des entiers, il n'aura pas besoin de la même place en mémoire.

Tableaux dynamiques

En Python, notre langage favori, les tableaux sont spéciaux.

Ce sont des tableaux dynamiques. Cela veut dire que l'on peut changer leur taille et que l'on peut les remplir avec des données de types différents.

*Ne vous en souciez pas trop mais gardez en tête que ce n'est pas la situation normale.*

Manipulation en Python

En général, le type des tableaux s'appelle array alors qu'en Python le type des tableaux est list. Attention, ceci peut faire confusion avec le concept de liste qui correspond à autre chose.

indice (rang) et valeur

Dans le tableau tableau = [4, 12, 7, 32, 7] il faut distinguer la valeur contenue dans le tableau et son rang (numéro d'ordre)

  • 12 est une valeur contenue dans le tableau
  • le rang de 12 est 1 (les rangs sont numérotés à partir de 0. Le premier élément, 4, a le rang 0).
  • l'élément de rang 0 a la valeur 4
  • l'élément de rang 4 est 7
  • on trouve deux éléments de valeur 7, aux rangs 2 et 4.

Manipulations de base

tableau = [112, 9, 17, 15, 28]
tableau[0]      # renvoie l'élément de rang 0 : 112
tableau[1]      # renvoie l'élément de rang 1 : 9
tableau[2] = -6 # modif. de l'élément de rang 2
len(tableau)    # renvoie le nombre d'éléments du tableau, donc ici 5
9 in tableau    # renvoie True puisque 9 est un élément de tableau
tableau[6]      # renvoie une IndexError puisque le rang maximal est ici 4

Contrairement au tuple, le tableau est mutable. On peut le modifier. Cette commande est donc autorisée :

tableau = [112, 9, 17, 15, 28]
tableau[2] = -6

Cela peut entraîner des surprises. Exemple avec python tutor

a = [1, 2, 3]
b = a
b[0] = 9
print(a)

Ajouter un élément

Comme déjà dit, normalement un tableau a une taille fixe et on ne peut pas lui ajouter d'éléments.

Mais en Python, on peut. Et c'est souvent assez pratique de raisonner sur un tableau vide que l'on remplit au fur et à mesure.

La méthode append est donc très utile :

tableau.append(3) # ajoute 3 à la fin du tableau

On peut aussi utiliser (moins utile) :

del tableau[1]    # supprime l'élément
tableau.pop()     # enlève et renvoie le dernier élément

Slicing

Python permet une manipulation plus avancée et très efficace. On appelle cela des slices (tranches).

p = [4, 17, 9, 41, 45, 1, 9]
p[-1]   # renvoie le dernier élément
p[-2]   # renvoie l'avant-dernier élément
p[2:]   # renvoie une copie du tableau à partir du rang 2
p[:4]   # renvoie une copie du tableau jusqu'au rang 4 non inclus
t[2:4]  # renvoie une copie du tableau du rang 2 au rang 4 non inclus
t[0:25] # renvoie une copie du tableau.
        # dans ce cas, l'indice trop élevé n'entraîne pas d'erreur
t[0:5:2] # renvoie une copie, des indices 0 à 5 (non inclus) par saut de 2
t[0:5:-1] # renvoie une copie, des indices 0 à 5 (non inclus) en ordre inverse
t[::-1] # renvoie une copie, du tableau en ordre inverse

Énumaration avec boucle pour [for]

Par valeur contenue dans le tableau

Exemple d'un calcul de somme.

tableau = [12, 5, 4, 17, 29]
total = 0
for item in talbleau:
    total += item
print(total)

les éléments ajoutés à total sont les éléments du tableau si bien qu'en fin de programme, la valeur affichée sera $12 + 5 + 4 + 17 + 29 = 67$

Par indice (rang)

Exemple de la recherche des écarts d'un élément au suivant.

tableau = [122, 35, 104, 17, 29]
n = len(tableau)
for i in range(n-1):
    ecart = tableau[i+1] - tableau[i-1]
    print(ecart)

Par indice et item

Si on parcours par indice, on a automatiquement l'item :

tableau = [122, 35, 104, 17, 29]
n = len(tableau)
for i in range(n):
    item = tableau[i]
    print("indice :",i," et valeur :",item)

Mais on trouve plus élégant d'écrire (*exactement le même résultat*)

tableau = [122, 35, 104, 17, 29]
for i, item in enumerate(tableau):
    print("indice :",i," et valeur :",item)

Cette écriture est plus compacte et sera pratique en cas de tableau donné en compréhension.

Tableau en compréhension

Il existe une façon élégante de fabriquer un tableau.

Exemple : Écrire le programme donnant les 100 premiers carrés :

$$1^2,\,2^2,\,3^2,\,\cdots\,=\, 1,\, 4,\, 9,\, \cdots$$

Solutions :

  • On peut créer le tableau à la main : [1,4,9,...] mais c'est long et peu satisfaisant…
  • On peut créer un tableau en ajoutant les éléments au fur et à mesure, le tableau fonctionnant comme un accumulateur :
    t = []
    for i in range(101):
        t.append(i**2)
    
  • On crée le tableau en compréhension, ce qui fait la même chose mais de façon plus compacte :
    t = [i**2 for i in range(101)]
    

    Vous pouvez remarquer que ces deux options contiennent les mêmes ingrédients, mais dans le second cas, la déclaration de la boucle for est dans la déclaration du tableau. Cela ressemble à la notation mathématique : en mathématique, si on parle de l'ensemble des carrés des entiers naturels de 0 à 100, on écrira $\left\lbrace n^2, n \in [[0 ; 100]]\right\rbrace$.

Tableau comme argument de fonction

On transmet des arguments au fonction. En principe les variables transmises ne sont pas modifiées.

Cas d'une variable simple

Voici le cas d'un entier - voir sur python tutor

def f(x):
    x = x + 3

y = 12
f(y)
print(y) # affiche 12 ou 15 ?
  • ligne 5, la fonction f est appelée avec l'argument y,
  • exécution de la fonction ligne 1 :
    • création d'une variable x qui vivra le temps de l'exécution de f
    • x commence en recopiant la valeur de y donc x = 12
    • ligne 2, x est modifié, mais cela n'a pas d'effet sur y
    • fin de la fonction, x est supprimé de la mémoire, y n'a pas été modifié
  • ligne 6, on affiche y donc 12.
Cas d'un tableau

Voir l'exécution sur python tutor.

def f(x):
    x[0] = 19

y = [10, 52, 27, 48]
f(y)
print(y[0]) # affiche 10 ou 19 ?

  • ligne 4, création du tableau y. y ne contient pas le tableau mais un lien permettant d'atteindre le tableau (on parle de pointeur).
  • ligne 5, la fonction f est appelée avec l'argument y,
  • exécution de la fonction ligne 1 :
    • création d'une variable x qui vivra le temps de l'exécution de f
    • x commence en recopiant la valeur de y. Donc x copie le lien vers le tableau. Ce n'est pas le tableau lui-même qui est copié, seulement le lien permettant d'atteindre le tableau en mémoire. Par conséquent x pointe vers le même contenu mémoire que y
    • ligne 2, x[0] est modifié, c'est à dire la case 0 du tableau pointé par x. Mais c'est le même que le tableau pointé par y. Le tableau pointé par y est donc modifié : x[0] = y[0] = 19.
    • fin de la fonction, x est supprimé de la mémoire.
  • ligne 6, on affiche y[0] donc 19.
nsi/langages/python/tableaux.txt · Dernière modification : de goupillwiki