Connexion élèves

Choisir le(s) module(s) à installer :

Tableaux et tuples

On l'a vu, Python propose 4 types de données de base ( pour rappel : int, float, str et bool ).

A partir de là, il est possible de "construire" ses propres types de données à partir des précédents.

Prenons un exemple : on voudrait stocker dans un script l'ensemble des notes des élèves d'une classe; il faut donc autant de variables qu'il y a de notes, et ce pour chacun des élèves :

Un seul élève

Pour un seul élève, ça va encore...

Plusieurs élèves

Ensuite, ça ne devient plus gérable...

Il serait alors judicieux de regrouper les notes d'un même élève dans un même ensemble, correspondant à un nouveau type de données appelé par exemple notes; chaque élève correspondrait alors à une "variable" différente de ce nouveau type, mais au contraire des types de base, elles stockeraient plusieurs données à la fois, regroupées sous le même nom :

Le type eleve

Le type notes

Plusieurs élèves

Plusieurs variables du type notes

Un nouveau type de donnée, construit à partir d'autres types...

C'est ce que permettent de faire les p-uplet ( 1-uplet, 2-uplet, 3-uplet..., p étant le nombre d'éléments stocké(s) ) et les tableaux.

Ils correspondent en informatique à un ensemble de données ( une "collection" ), rassemblées de façon à pouvoir y accéder facilement. Chaque donnée correspond à un élément différent de l'ensemble.
Dans de nombreux langages, ces éléments doivent être du même type, mais ce n'est pas le cas en Python : on peut mettre dans un p-uplet ou un tableau Python des données de type différent, mais c'est à éviter pour des raisons de lisibilité.

Chaque élément d'un tuple ou tableau correspond donc à une "case" dans laquelle on placerait une donnée. L'ordre dans lequel les données sont rangées permettra alors de les retrouver en désignant la bonne "case" dans laquelle elle est contenue.

45 3.2 27.246 'truc' 78 'bidule' 423 785 2.3 7.896 True ...

En Python, les p-uplet sont implémentés avec le type tuple.

Les tableaux sont eux implémentés à l'aide du type de données list, appelé liste Python, mais il s'agit d'un nom qui peut prêter à confusion, car une "liste" en informatique correspond à un concept bien différent du tableau ( concept que vous verrez d’ailleurs en Terminale si vous continuez la spécialité NSI ).
Il y a des raisons pour que les concepteurs du langage Python aient quand même choisi le nom "liste" pour désigner les tableaux, mais nous ne nous étendrons pas là-dessus.

Nous utiliserons dorénavant toujours le mot "tableau" pour désigner ce type de données, mais ne vous étonnez pas de trouver le mot "liste" dans d'autres cours ou sur Internet.

La grosse différence entre tuple et tableau est la suivante :

Un tableau ou un tuple a un nom : ce nom est commun à l'ensemble des données stockées dans le tuple ou le tableau; on le choisit arbitrairement, mais comme pour les variables, il y a certaines restrictions dans ce choix : on ne peut pas utiliser les termes du langage Python lui-même, le nom ne doit pas commencer par un chiffre ni un caractère autre qu'une lettre, il ne doit pas y avoir d'espace,...
On peut utiliser des lettres majuscules, sauf au début du nom.

Manipulation des tuples et des tableaux

Repérage d'un élément

Chaque élément d'un tuple ou d'un tableau est repéré par son indice ( ou index ), qui représente la position de la donnée stockée ( en gros, le numéro de la "case" où la donnée est stockée ) depuis le début du tuple ou tableau.

Attention : comme beaucoup de choses en informatique ( comme par exemple les chaînes de caractères ), la numérotation des indices commence non pas à 1 mais à 0 : la première donnée a l'indice 0, la deuxième l'indice 1, la troisième 2, etc....

Indice 0 1 2 3 4 5 6 7 8 9 10
Valeur 45 3.2 27.246 45.6 78 12 423 785 2.3 7.896 5

Pour adresser un élément particulier du tuple/tableau, on utilise alors la syntaxe suivante :


nom_du_tableau[indice_de_l_element]
			

...qui désigne alors la valeur stockée dans l'élément adressé.

Bien entendu, il faut que l'indice soit bien dans les limites "permises" du tableau, c'est à dire être compris entre 0 ( indice du premier élément ) et n - 1 ( n = nombre d'éléments du tableau ).

---------------------------------------------
| indices | 0 | 1 | 2 | 3 | ... | n-2 | n-1 |
---------------------------------------------
| valeurs | . | . | . | . | ... |  .  |  .  |
---------------------------------------------
				

Dans le cas où l'on "sort" du tableau, Python signale une erreur IndexError : Index out of range ( que vous rencontrerez de trop nombreuses fois !! )

Exemples pour le tuple/tableau ci-dessus, nommé tup_tab :


tup_tab[0] == 45
tup_tab[3] == 45.6
tup_tab[8] == 2.3	
tup_tab[12] → IndexError !
			

C'est donc tout à fait le même "mode de fonctionnement" que les chaînes de caractères...

Attention, une erreur classique est de confondre l'indice d'un élément dans le tuple ou le tableau, et la valeur stockée dans cet élément.

Pour simplifier :

  • un élément = une "case" dans un tuple ou un tableau
  • l'indice d'un élément = le numéro de la "case"
  • la valeur = le contenu de la "case"
Arrays start at 1

Affichage

Pour afficher un élément d'un tuple/tableau, utiliser la syntaxe précédente :


>>> print(tup_tab[8])
2.3
	
>>> print(tup_tab[3])
45.6
				

Pour afficher le tuple/tableau complet, utiliser son nom général :


>>> print(tup_tab)
[45, 3.2, 27.246, 45.6, 78, 12, 423, 785, 2.3, 7.896, 5] # ou (45, 3.2, 27.246, 45.6, 78, 12, 423, 785, 2.3, 7.896, 5) si c'est un tuple !
			

Nombre d'éléments dans un tuple ou un tableau

Pour trouver le nombre d'éléments présents dans un tuple ou un tableau, utiliser l'instruction len() :


>>> print(len(tup_tab))
11		
			

Modification d'un élément

Comme on l'a dit plus haut, cela n'est possible qu'avec les tableaux et pas les tuples.

Jusqu'à maintenant, vous avez vu des types de données ( int, float, str,...et maintenant tuple ) qui sont immuables : cela signifie que les variables de ces types ne peuvent pas être modifiées; la seule façon de les "réutiliser" est en fait de leur réaffecter une nouvelle valeur, ce qui se traduit en réalité par la création d'une nouvelle variable portant le même nom, "l'ancienne" étant effacée de la mémoire :

Pour visualiser cela, nous allons utiliser la fonction Python id(variable), renvoyant l'identifiant unique d'une variable, qui est différent pour des variables différentes :

a = 38 # initialisation print(a, id(a)) a = a + 1 # incrémentation. print(a, id(a)) # En réalité, Python créé une NOUVELLE variable portant le nom 'a' et efface l'ancienne a = 45 # réaffectation. print(a, id(a)) # Là aussi, 'a' est en réalité une NOUVELLE variable

Les tableaux sont eux au contraire muables ( mutable en anglais ) : cela signifie que l'on peut en modifier un élément sans avoir à complètement réaffecter au tableau de nouvelles données :

t1 = ['a', 'b', 'b', 'd'] print(t1, id(t1)) t1[2] = 'c' # on modifie le 3ème élément sans réaffecter TOUT le tableau print(t1, id(t1)) # 't1' est toujours la MEME variable. t1.append('e') # idem si on rajoute un élément à la fin du tableau (voir plus bas) print(t1, id(t1))

On dit dans ce cas que l'on modifie un tableau par mutation ( et donc pas par réaffectation ); dans ce cas, Python n'a alors pas besoin de créer une nouvelle variable.

Bien entendu, rien n'empêche cependant de réaffecter à une variable un tableau complètement nouveau !

Ce mode de fonctionnement est bien pratique, mais peut entraîner des problèmes, par exemple lors de la copie d'un tableau, problèmes que nous évoquerons plus tard.

Concaténation de deux tableaux

On rappelle que concaténer signifie "ajouter à la suite de".

Comme pour les chaînes de caractère, l'opérateur + permet de concaténer deux tableaux en un plus grand :


tableau1 = [1 , 2 , 3]
tableau2 = [4 , 5 , 6]
tableau1 = tableau1 + tableau2 # on pourrait si on voulait créer aussi un troisième tableau

print(tableau1)
			

[1 , 2 , 3 , 4 , 5 , 6]					
			

Initialisation/création d'un tuple ou d'un tableau

Création par instanciation ( "de toute pièce" )

C'est la seule méthode pour créer un tuple. On décrit l'ensemble des éléments, séparés par des virgules; la syntaxe change pour les tuples et les tableaux :


	tableau1 = [45, 32, 27, 189, 78, 569, 423, 785, 23, 78, 630] # utilisation de crochets pour les tableaux
	
	noms = ('durand', 'martin', 'roger', 'paul', 'dubois', 'jean') # utilisation de parenthèses pour les tuples		
			

Pour les tableaux uniquement

Création d'un tableau vide

Vous aurez parfois besoin d'initialiser un tableau vide, c'est à dire n'ayant aucun élément :


tableau_vide = []	
				

"Remplissage automatique"

Pour remplir automatiquement un tableau avec un nombre donné d'éléments tous identiques :


tableau1 = [None]*100  # crée un tableau contenant 100 éléments tous égaux à None ( = "rien" )
tableau2 = [0]*10  # crée un tableau contenant 10 éléments tous égaux à 0			
			

( Vous aviez déjà vu cette façon de faire avec les chaînes de caractères...)

Création à l'aide d'une boucle

Méthode 1

La première idée est de créer un tableau ayant un certain nombre d'éléments de valeur quelconque dans un premier temps ( None par exemple, qui signifie "rien" ), et de "remplir" ensuite chaque "case" avec une valeur :


tab = [None]*10  # création d'un tableau de 10 éléments tous égaux à 'None'

for i in range(10):
	tab[i] = 2**i 		# "remplit" chaque élément avec une puissance croissante de 2
	
print(tab)	
			

[1, 2, 4, 8, 16, 32, 64, 128, 256, 512]			
			
Méthode 2

A partir d'un tableau ne contenant initialement aucun élément ( = tableau vide ), on "ajoute" les éléments les uns après les autres à la fin du tableau qui se construit donc petit à petit; pour cela, on utilise une méthode particulière associée aux listes Python, la méthode append :


tab = [] # tableau vide

for i in range(10):
	tab.append(2**i) # "append" = "ajouter à la fin"	
			

Il existe une autre syntaxe, équivalente à la précédente : :


tab = []

for i in range(10):
	tab = tab + [2**i]
			

Mais vous verrez en Terminale qu'elle est moins efficace que la précédente : on préférera donc utiliser la méthode append.

Les tableaux par compréhension

Attention, méthode très puissante, mais pas évidente à maîtriser. Mais elle est au programme et sera dorénavant très utilisée !

C'est une méthode de création de tableau équivalente aux deux précédentes, mais en beaucoup plus concis :


tableau1 = [i for i in range(10)] # crée un tableau contenant 10 éléments de 0 à 9 	

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>		
			

tableau2 = [2*i for i in range(10)] # crée un tableau contenant 10 éléments, chaque élément étant le double du compteur i 	

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>>		
			

tableau3 = [2*i for i in range(10) if i%3 == 0 ] # crée un tableau contenant les éléments double du compteur i, mais uniquement si i est divisible par 3

[0, 6, 12, 18]
>>>		
			

L'expression peut être plus ou moins complexe selon ce que l'on veut faire ! On peut même y mettre des conditions complexes, des boucles imbriquées, etc...

Autres fonctions sur les tuples et les tableaux

Détermination de l'indice d'un élément donné

Pour déterminer l'indice d'une valeur particulière dans un tuple ou un tableau ( ça peut servir...), utiliser la fonction index() :


>>>tableau4 = ['lundi','mardi','mercredi','jeudi','vendredi','samedi','dimanche']

>>> print(tableau4.index('mercredi'))
2		
			

Attention si il y a des doublons : la fonction méthode() ne donne que l'indice du premier élément rencontré ayant la valeur recherchée.

Si la valeur cherchée n'est pas dans le tableau, une erreur est renvoyée.

Test d'appartenance d'une valeur

On peut tester la présence de telle ou telle valeur dans un tuple ou un tableau en utilisant l'opérateur in :


if 45 in tup_tab : # renvoie True
	print("Valeur présente")
		
if 214 in tup_tab : # renvoie False
	print("Valeur absente")	
			
			

Tuple ou tableau ?

Quand utiliser un tuple ou un tableau ?

Vous venez de voir que les tableaux sont bien plus "souples" que les tuples, et vous en viendrez alors vite à vous demander quel est l'intérêt de ces derniers : pourquoi ne pas toujours utiliser des tableaux ?

Il faut bien voir que leur stockage en mémoire n'est pas du tout le même :

On aura donc intérêt à utiliser les tuples quand on n'aura à stocker que des données constantes au cours d'un programme.

Les tuples dans les fonctions

Les tuples sont également mis en œuvre lorsqu'une fonction doit renvoyer plusieurs résultats.

Voila par exemple la définition d'une fonction qui calcule et renvoie le quotient et le reste de la division entière de deux entiers :


def division_entiere(n1:int, n2:int) -> int:
	quotient = n1 // n2
	reste = n1 % n2
	return quotient, reste   # renvoi des deux valeurs sous forme d'un tuple ( les parenthèses sont optionnelles dans cette situation )		
			

Les deux résultats quotient et reste sont renvoyés sous forme d'un tuple au programme principal.

Il faudra donc penser que le type de la variable utilisée lors de l'appel de la fonction depuis le programme principal sera un tuple :


resultat = division_entiere(146, 78) # affectation du résultat renvoyé par la fonction au tuple 'resultat'

print("Le quotient est égal à", resultat[0])
print("Le reste est égal à", resultat[1])	
			

On peut également récupérer les deux résultats du tuple...directement dans un tuple de deux éléments :


quotient, reste = division_entiere(146, 78) # affectation du résultat renvoyé au tuple (quotient, reste) ( là non plus, les parenthèses ne sont pas obligatoires )
										# bien entendu, les éléments de ce tuple doivent être dans le même ordre que celui de la fonction !
print("Le quotient est égal à", quotient)
print("Le reste est égal à", reste)	
			

Vous rencontrerez assez souvent des fonctions renvoyant des tuples de plusieurs résultats, faites attention quand c'est le cas !

QCM d'entraînement

Exercices

Manipulation de base sur les tableaux

Définir le tableau [17, 38, 10, 25, 72] en lui donnant un nom, puis effectuez les actions suivantes :

  • afficher le tableau complet
  • afficher le troisième élément du tableau ( '10' ).
  • afficher l’indice de l’élément '25' ( = 3 )
  • modifier l’élément '38' et afficher le tableau
  • créer un nouveau tableau qui contient 3 fois les éléments du tableau précédent dans le même ordre, puis l'afficher
  • afficher le nombre d'élément de ce nouveau tableau

Lien vers les RÉPONSES

Création de tableaux

Créer à l'aide d'une boucle , puis afficher les tableaux suivants :

  • un tableau contenant 10 zéros
  • un tableau contenant les nombres pairs de 0 à 50, un autre contenant les nombres impairs de 1 à 51.
    On rappelle qu'un nombre est pair si le reste de sa division par 2 est égal à 0.
  • un tableau contenant 10 entiers aléatoires de valeur comprise entre 1 et 100. ( utiliser la fonction randint(a,b) du module random ).
  • un tableau de 20 nombres alternant entre 0 et 1 ([0, 1, 0, 1, 0, ...]).
    Vous utiliserez pour cela la parité de l’indice de la boucle ( la variable i de l’instruction for i in range(...))
  • un tableau de 100 nombres alternant entre −1 et 1 ([1, -1, 1, -1, 1, ...]). Vous pourrez utiliser astucieusement l’indice de la boucle... mais il existe de nombreuses autres approches !
  • un tableau contenant les résultats de la table de multiplication de 7, en allant de 7 x 0 à 7 x 12.

Lien vers les RÉPONSES

Création de tableaux par compréhension

Reprendre les exercices précédents mais en utilisant cette fois la méthode de création par compréhension.

Lien vers les RÉPONSES

Applications

Les tableaux et les tuples sont des types de données, ils peuvent donc très bien être utilisés comme paramètre/argument de fonction, ou alors de résultat renvoyé par une fonction.

Dans la signature des fonctions, il va falloir préciser les annotations de type concernant les tuples et les tableaux : on indiquera leur propre type ( tuple ou list ) mais également celui des données qu'ils vont contenir; la syntaxe utilise pour cela les crochets.

Par exemple, pour une fonction qui prend en paramètre un tableau d'entiers et renvoie un flottant :


def fonction(tab: list[int])->float:
	...	
			

Et pour une fonction qui prend en paramètre une chaîne de caractère, et renvoie un tuple de chaînes de caractères :


def fonction(mot: str)->tuple[str]:
	...	
			

Moyenne annuelle

  1. Compléter la fonction moyenne_annuelle() ci-dessous qui prend en paramètre un tuple de trois nombres flottants compris entre 0 et 20 et renvoie la moyenne de ces trois nombres.
  2. Effectuer le jeu de tests suivant :
    • moyenne_annuelle((12, 13, 14)) == 13
    • moyenne_annuelle((8, 13, 14)) == 11.666666666666666
    • moyenne_annuelle((0, 5, 16)) == 7
    • moyenne_annuelle((12.54, 13.12, 14.58)) == 13.413333333333332
    • moyenne_annuelle((12.99, 17.21, 15.84)) == 15.34666666666667
def moyenne_annuelle(notes: tuple[float])->float: pass

Lien vers les RÉPONSES

Le cadavre exquis

Le cadavre exquis est un « jeu qui consiste à faire composer une phrase, ou un dessin, par plusieurs personnes sans qu'aucune d'elles ne puisse tenir compte de la collaboration ou des collaborations précédentes

La méthode choice() du module random permet de tirer au sort un élément dans un itérable non vide (et donc dans un tableau non vide) :


from random import choice
				
tab = ['chat', 'chien', 'cheval', 'vache', 'cochon']

animal = choice(tab)
				
  1. Compléter la fonction cadavre_exquis ci-dessous qui prend en paramètre :
    • un tableau de noms non vide,
    • un tableau de verbes non vide,
    • un tableau de compléments non vide,
    et qui renvoie une phrase aléatoire construite selon le principe du cadavre exquis : en piochant un nom dans le tableau de noms, puis en piochant un verbe dans le tableau de verbes et enfin en piochant un complément dans le tableau de compléments.
  2. Utiliser la fonction avec les 3 tableaux ci-dessous.
from random import choice def cadavre_exquis(noms: list[str], verbes: list[str], complements: list[str])->str: pass n = ['Le chasseur', 'La présidente', 'Le lapin', 'Pikachu', 'La comète', 'La licorne', 'Le prof'] v = ['mange', 'cherche', 'entretient', 'admire', 'vénère', 'admoneste', 'contemple'] c = ['la gazinière.', 'la forêt.', 'la rencontre.', 'la bicyclette.', 'le micro-processeur.', "l'élève."]

Lien vers les RÉPONSES

Lancer de dés

Dans cet exercice, une fonction doit créer un tableau et le renvoyer.

Pour la création du tableau, choisir la méthode que vous préférez !! ( n'oubliez pas qu'il faut toutes les connaître..)

On lance successivement cinq dés à six faces et on souhaite mémoriser les résultats obtenus dans un tableau.

  1. Compléter la fonction lancer_cinq_des ci-dessous afin qu'elle renvoie un tableau contenant les résultats aléatoires de cinq lancers de dés..
  2. Compléter la fonction lancer_n_des qui prend en paramètre un nombre entier positif n et renvoie un tableau de longueur n correspondant au résultat d'un lancer de n dés. Pour cela, on adaptera la fonction précédente.
from random import randint def lancer_cinq_des()->list[int]: pass def lancer_n_des(n: int)->list[int]: pass

Lien vers les RÉPONSES