Types construits

Les types de données dits « simples » sont :

  • int (nombres entiers) ;
  • float (nombres flottants) ;
  • bool (booléens) ;
  • str (chaînes 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 bien t = ("a", "b", "c", 3) pour un tuple à 4 éléments ;
  • t = "a", ou bien t = ("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−1n 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 Python list() : le nom list ferait alors référence à la variable list et plus à la fonction list(), qui ne serait plus disponible, tant qu’on n’aurait pas détruit la variable list par l’instruction del 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 !
Activité
Prédire (sans utiliser Python) les valeurs de lst1 et lst2 après la suite d’instructions suivante :
>>> lst1 = ['a', 'b', 'c']
>>> lst2 = lst1+['d']
>>> lst1[0] += 'z'
×
 » remove= »  » size=’20’/]
×
 » remove= »  » size=’20’/]

 

 

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] :

sclicing

Ainsi :

>>> L[1:4]
['deux', 3, 'quatre']
Activité
Tester les instructions suivantes et analyser les résultats avec attention :
>>> L[:2]
>>> L[0:len(L)]
>>> L[:]
>>> L[2:5]
>>> L[2:7]
>>> L[-2:-4]
>>> L[-4:-2]
>>> L[-2]
>>> L[-1]
Écrire une instruction qui permet d’obtenir la liste inverse d’une liste, uniquement par slicing.

L[

×
]

 

 

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 type range (un itérateur) , et non une liste. Pour afficher son contenu, on peut le convertir en liste, grâce à l’instruction list() :

>>> 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é.

 

 

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *