Types construits
Les types de données dits « simples » sont :
int
(nombres entiers) ;float
(nombres flottants) ;bool
(booléens) ;str
(chaîne de caractères).
Ces types simples ne sont plus suffisants si nous avons besoin de garder en mémoire un grand nombre de valeurs.
Exemple : pour mémoriser 100 nombres, il n’est pas raisonnable de les mémoriser chacun dans une variable différente :
a1 = 12 a2 = 54 a3 = -9 ...
comment accéder au ième nombre ? si je supprime le nième, quel rang aura le pième ? comment les trier ? comment rechercher une valeur en particulier ?
D’autre part, si l’on souhaite manipuler des valeurs au sein d’une unique entité, il faudrait pouvoir les regrouper.
Exemple : pour représenter les coordonnées d’un unique point dans l’espace, il faut trois valeurs (x, y, z) de type float, il faudrait les regrouper dans un unique « conteneur ».
L’objectif est donc de construire un type de données capable de contenir plusieurs valeurs.
Ceci amène à la construction d’objets conteneurs capables de contenir plusieurs objets, simples ou eux-même construits.
Les tuples
Un p-uplet (type tuple), est une suite ordonnée d’éléments qui peuvent être chacun de n’importe quel type.
Création d’un p-uplet
Pour créer un p-uplet non vide, on écrit des valeurs séparées par des virgules. Par exemple :
t = "a","b","c", 3
ou bient = ("a", "b", "c", 3)
pour un tuple à 4 éléments ;t = "a",
ou bient = ("a",)
pour un tuple à 1 éléments (attention à la virgule) ;t = ()
pour un tuple à 0 éléments (ici, pas de virgule, mais des parenthèses obligatoires).
Pour écrire un p-uplet qui contient un n-uplet, l’utilisation de parenthèses est nécessaire. Voici un exemple avec un tuple à 2 éléments dont le second est lui-même un tuple : t = 3, ("a","b","c")
Remarque : en général, les parenthèses sont obligatoires dès que l’écriture d’un p-uplet est contenue dans une expression plus longue. Dans tous les cas, les parenthèses peuvent améliorer la lisibilité.
Opérations
Nous avons deux opérateurs de concaténation qui s’utilisent comme avec les chaînes de caractères, ce sont les opérateurs +
et *
. De nouveaux p-uplets sont créés.
>>> t1 = "a", "b" >>> t2 = "c", "d" >>> t1 + t2 ('a','b','c','d') >>> 3 * t1 ('a','b','a','b','a','b')
Appartenance
Pour tester l’appartenance d’un élément à un tuple, on utilise l’opérateur in
:
>>> t = "a", "b", "c" >>> "a" in t True >>> "d" in t False
Utilisation des indices
Les indices sont des entiers qui font référence aux positions des éléments dans le tuple.
La notation est comparable à celle utilisée avec les suites en mathématiques (\(u_0,u_1,u_2,…\)) : les indices commencent à 0.
Exemple : dans le tuple ("a", 1,"b", 2,"c", 3)
, l’élément d’indice 0 est "a"
et celui d’indice 3 est 2
.
Pour accéder à un élément d’indice i
d’un tuple t
, la syntaxe est t[i]
.
L’indice i
pouvant prendre les valeurs entières de 0
à n−1
où n
est la longueur du tuple. Cette longueur s’obtient avec la fonction len()
:
>>> t ="a", 1,"b", 2,"c", 3 >>> len(t) 6 >>> t[2] 'b'
Les éléments d’un tuple ne sont pas modifiables par une affectation de la forme
t[i] = valeur
.
Cela provoque une erreur !
Le dernier élément d’un tuple t
a pour indice len(t)-1
. On accède ainsi au dernier élément avec t[len(t)-1]
qui peut s’abréger en t[-1]
.
>>> t = "a", 1, "b", 2, "c", 3 >>> t[-1] 3 >>> t[-2] 'c'
Exemple avec des tuples emboîtés (un tuple contenant des tuples) :
>>> t = ("a", "b"), ("c", "d") >>> t[1][0] 'c'
Explication : t[1]
est le tuple ("c", "d")
et "c"
est l’élément d’indice 0
de ce tuple.
Affectation multiple
Prenons pour exemple l’affectation a, b, c = 1, 2, 3
. Ceci signifie que le tuple (a, b, c)
prend pour valeur le tuple (1, 2, 3)
, autrement dit, les valeurs respectives des variables a
, b
et c
sont 1
, 2
et 3
. En particulier, l’instruction a, b = b, a
permet d’échanger les valeurs des deux variables a
et b
. Les valeurs des éléments d’un tuple peuvent ainsi être stockées dans des variables.
>>> t = 1, 2, 3 >>> a, b, c = t >>> b 2
Cette syntaxe s’utilise souvent avec une fonction qui renvoie un tuple. Voici un exemple avec une fonction qui calcule et renvoie les longueurs des trois côtés d’un triangle ABC. La fonction prend en paramètres trois p-uplets représentant les coordonnées des trois points.
from math import sqrt def longueurs(A, B, C): xA,yA = A xB,yB = B xC,yC = C dAB= sqrt((xB - xA) ** 2 + (yB - yA) ** 2) dBC= sqrt((xC - xB) ** 2 + (yC - yB) ** 2) dAC= sqrt((xC - xA) ** 2 + (yC - yA) ** 2) return dAB, dBC, dAC
La fonction étant définie, nous l’utilisons dans l’interpréteur :
>>> M = (3.4, 7.8) >>> N = (5, 1.6) >>> P = (-3.8, 4.3) >>> dMN, dNP, dMP = longueurs(M, N, P) >>> dMN 6.4031242374328485
Les listes
Une liste est un objet pouvant en contenir d’autres (de n’importe quel type), organisés séquentiellement (les uns à la suite des autres).
Exemple : la liste L
suivante contient des entiers, des chaînes de caractères et un nombre flottant.
À la différence des tuples, les listes sont modifiables, et possèdent de nombreuses méthodes pour cela…
Accès aux éléments d’une liste
Une liste est ordonnée : on accède à ses éléments en indiquant leur indice (index en anglais).
>>> L = [] # Une liste vide >>> L [] >>> L = [1, 'deux', 3, 'quatre', 5.0, 6] # Une liste qui contient différents types d'objets >>> L [1, 'deux', 3, 'quatre', 5.0, 6] >>> L[2] # Accès au 3ième (indice 2) élément de la liste 3 >>> len(L) # nombre d’éléments dans la liste 6 >>> L[6] # la liste n'a pas d'élément d'indice 6 ! Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range
ATTENTION : il ne faut pas nommer la variable
list
, sous peine de « cacher » l’instruction Pythonlist()
: le nomlist
ferait alors référence à la variablelist
et plus à la fonctionlist()
, qui ne serait plus disponible, tant qu’on n’aurait pas détruit la variablelist
par l’instructiondel list
.
Liste = objet muable
Les listes sont des objets muables (mutable en anglais). Cela signifie que le nom d’une liste désigne l’emplacement de la liste dans la mémoire, et non la liste elle-même.
objet immuable >>> x = 3.2 >>> y = x >>> y +=1 >>> y 4.2 >>> x 3.2 >>> id(x), id(y) (36418024, 36418012) # 2 objets différents ! |
objet muable >>> x = [4,2,5] >>> y = x >>> y += [3,9] >>> y [4, 2, 5, 3, 9] >>> x [4, 2, 5, 3, 9] >>> id(x), id(y) (4494886456, 4494886456) # un seul et même objet ! |
Découpage ou Slicing
Le slicing (saucissonage) permet d’obtenir une sous-liste depuis une liste.
La syntaxe est la suivante (en gros 7 possibilités) :
liste[debut:fin:pas] liste[debut:fin] liste[debut:] liste[:fin] liste[::pas] liste[debut::pas] liste[:fin:pas]
debut
: indice du premier éléments à sélectionner (par défaut : le premier élément de la liste)fin
: indice du dernier élément exclu à sélectionner (par défaut : le dernier élément de la liste)pas
: 1 par défaut
Pour extraire une sous-liste, il faut imaginer que les indices représentent non pas les tranches de saucisson, mais les coups de couteau qui vont permettre de couper les tranches (en partant de 0 pour l’entame).
Soit la liste L = [1, 'deux', 3, 'quatre', 5, 6]
:
Ainsi :
>>> L[1:4] ['deux', 3, 'quatre']
Créer une liste
par la fonction range()
>>> range(9) range(0,9) >>> type(range(9)) <class 'range'>
Remarque : depuis la version 3 de Python, la fonction
range()
renvoie un objet de typerange
(un itérateur) , et non une liste. Pour afficher son contenu, on peut le convertir en liste, grâce à l’instructionlist()
:
>>> list(range(9)) [0, 1, 2, 3, 4, 5, 6, 7, 8] >>> list(range(2, 60, 10)) # comme pour le « slicing » [2, 12, 22, 32, 42, 52]
Modifier une liste
par opérations
Deux opérateurs sont reconnus :
- la concaténation de deux listes :
liste1 + liste2
- la multiplication par un entier :
liste * entier
>>> ['a']*12 ['a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'] >>> (["L'informatique"]+["c'est"]+["Fantastique"])*2 ["L'informatique", "c'est", "Fantastique", "L'informatique", "c'est", "Fantastique"]
par ajout d’éléments
- ajout à la fin :
>>> l = ['riri', 'fifi'] >>> l.append('loulou') >>> l ['riri', 'fifi', 'loulou']
- insertion :
>>> l.insert(1, 'Donald') >>> l ['riri', 'Donald', 'fifi', 'loulou']
par remplacement d’éléments
>>> l[1] = 'Picsou' >>> l ['riri', 'Picsou', 'fifi', 'loulou']
On peut également remplacer une portion entière de la liste, en utilisant le slicing :
>>> l[2:] = ['Daisy', 'Horace', 'Pluto'] >>> l ['riri', 'Picsou', 'Daisy', 'Horace', 'Pluto']
par suppression d’éléments
>>> del l[1] >>> l ['riri', 'Daisy', 'Horace', 'Pluto']
Ou également grâce à la méthode .remove()
:
>>> l.remove('Pluto') >>> l ['riri', 'Daisy', 'Horace']
Copier une liste
par « slicing »
>>> nliste1 = L[:] >>> id(nliste1), id(liste) (44948542180, 4494886456) # deux objets différents
avec le constructeur list()
>>> nliste2 = list(liste) [1, 'deux', 3, 'quatre', 5, 6]
Trier une liste
Tri sur place
>>> nliste1.sort() >>> nliste1 [1, 3, 5, 6, 'deux', 'quatre'] # c'est le même objet de type list, mais ordonnée.
Tri avec copie
>>> sorted(liste) [1, 3, 5, 6, 'deux', 'quatre'] # c'est un autre objet list : l'original existe toujours
Inverser une liste
>>> nliste1.reverse() >>> nliste1 ['quatre', 'deux', 6, 5, 3, 1] >>> nliste1[::-1] [1, 3, 5, 6, 'deux', 'quatre']
Chercher un élément dans une liste
La méthode .index()
permet d’obtenir l’indice d’un élément contenu dans une liste.
>>> Simpson = ['Homer', 'Marge', 'Bart', 'Lisa'] >>> Simpson.index('Bart') 2
Attention :
- Si l’élément recherché n’est pas dans la liste,
.index()
renvoie un message d’erreur.Il faudra donc tester l’appartenance de l’élément à la liste avant d’appeler
.index()
(voir page structures de contrôle).
- S’il existe plusieurs éléments identiques dans la liste, seul l’indice du premier sera renvoyé.