Afficher la pageAnciennes révisionsLiens de retourHaut de page Cette page est en lecture seule. Vous pouvez afficher le texte source, mais ne pourrez pas le modifier. Contactez votre administrateur si vous pensez qu'il s'agit d'une erreur. [[python:bases:dictionnaires|{{ :suivant.png?nolink&30|Dictionnaires}}]] [[:python:bases:listes|{{ :retour.png?nolink&30|Listes}}]] [[:python:accueilpython|{{ :iconemaison.jpg?nolink&30|Sommaire Python et microPython}}]] ===== Python - Tuples ===== [Mise à jour le : 31/1/2022] * **Source** * **Documentation** sur Python.org : <html> <html><a href="https://docs.python.org/fr/3.6/reference/index.html" target="_blank">référence du langage</a>, <a href="https://docs.python.org/fr/3/tutorial/datastructures.html#tuples-and-sequences" target="_blank">tuples et séquences</a>, <a href="https://docs.python.org/fr/3.6/library/stdtypes.html#sequence-types-list-tuple-range" target="_blank">types séquentiels list, tuple, range</a>, <a href="https://docs.python.org/fr/3.5/library/functions.html" target="_blank">fonctions natives</a></html> (built-in) * ** Mots-clés** : immuable, unpacking, tuple <callout type="warning" icon="true">Les mots ci-dessous sont dits "réservés". Ils ne peuvent pas être utilisés comme nom de variable. Les mots __soulignés__ sont une nouveauté de Python 3. Les mots en **gras** sont utilisés dans cette page.</callout> | and | continue | finally | is | raise | | as | def | for | lambda | return | | assert | del | from | __None__ | __True__ | | __async__ | elif | global | __nonlocal__ | try | | __await__ | else | if | not | while | | break | except | import | or | with | | class | __False__ | in | pass | yield | * <html><a href="https://docs.python.org/fr/3.5/library/functions.html" target="_blank">Fonctions natives</a></html>** (built-in)**((Fonctions toujours disponibles.)) utilisées dans les exemples : **list**(), **print**(), **range**(), **tuple**(). ---- ==== 1. Introduction ==== Le tuple est une séquence. Comme la liste, il référence des objets hétérogènes. On peut lui appliquer le test d'appartenance avec **in**, accéder aux différents éléments avec un crochet, faire du slicing etc. La raison d'être principale du type tuple est de construire des objets globalement immuables. <callout type="warning" icon="true">Un **tuple**, ou **P-uplet** est une liste de **constantes**. Il est **immuable** donc non modifiable. Les **parenthèses ( )** délimitent les **tuples**.</callout> ==== 2. Création ==== //Exemple// <code python *.py> # Affectation simple >>> tp = "a","b",4 # Création d'un tuple à 3 éléments >>> tp = () # Création d'un tuple vide (peu d'intérêt) >>> tp = 6, # un seul élément nécessite une virgule !!! # Les parenthèses sont obligatoires dès que l'écriture d'un tuple est contenu dans une expression plus longue. >>> tp = 3,(1,True,4.5,8, "a") # différent types >>> tp # renvoie (3, (1, True, 4.5, 8, 'a')) # Tuple contenant des tuples >>> t2d = (1,"a"), (2,"b") # équivalent à (1,"a"), # (2,"b") # Affectation multiple = tuple unpacking >>> a,b,c = 1,2,3 # a=1, b=2, c=3 </code> <callout type="warning" icon="true">Un tuple avec **un seul élément** nécessite une **virgule**.</callout> ==== 3. Accès aux éléments ==== Les indices permettent d'accéder aux différents éléments d'un tuple. Pour accéder à un élément d'indice i d'un tuple t, la syntaxe est t[i]. L'indice i peut prendre les valeurs entières de 0 à n-1 ou n est la longueur du tuple. <code python *.py> # Accès à une valeur en lecture tp = "a",2,8,7,"b" >>> tp # renvoie ('a', 2, 8, 7, 'b') >>> len(tp) # renvoie 5 >>> tp[2] # renvoie 8 # i peut être négatif ! >>> tp[-1] # renvoie "b" car on parcourt le tuple en partant de la fin </code> ==== 4. Construction ==== * **Issue d'une concatenation avec +** <callout type="primary" icon="true">Bien que le type tuple soit immuable, il est tout à fait légal d'"additionner" deux tuples, et l'"addition" va produire un **nouveau** tuple.</callout> //Exemple// <code python *.py> >>> tuple1 = (1, 2,) >>> tuple2 = (3, 4,) >>> print('Resultat:', tuple1 + tuple2) # Résultat: (1, 2, 3, 4) </code> * ** Issue d'une concaténation avec * ** //Exemple// <code python *.py> >>> tuple3 = 3*tuple1 # Renvoie (1,2,1,2,1,2) </code> * **Issue d'une liste** //Exemple// <code python *.py> >>> liste = list(range(10)) # résultat[0,1,2,3,4,5,6,7,8,9] >>> liste[9] = 'Inconnu' # résultat[0,1,2,3,4,5,6,7,8,'Inconnu'] >>> del liste [2:5] # résultat : [0, 1, 5, 6, 7, 8, 'Inconnu'] >>> mon_tuple = tuple(liste) # résultat : (0, 1, 5, 6, 7, 8, 'Inconnu') </code> ====5. Appartenance ==== Pour tester l'appartenance d'un élément à un tuple, on utilise l'opérateur **in**. <code python *.py> >>> t = "a","b","c" >>> "c" in t # renvoie True >>> "d" in t # renvoie False </code> ====6. Modification !==== <callout type="warning" icon="true">Comme l'objet est immuable, la modification est impossible. Il faut transformer le tuple en liste et créer un nouveau tuple à partir de la liste modifiée.</callout> //Exemple// <code python *.py> >>> tp = "a",2,8,7,"b" >>> tp # renvoie ('a', 2, 8, 7, 'b') >>> tp[2] = 3 # Renvoie une erreur car un tuple est immuable # Traceback (most recent call last): # File "<stdin>", line 1, in <module> # TypeError: 'tuple' object does not support item assignment >>> lst = list(tp) >>> lst # renvoie la liste ['a', 2, 8, 7, 'b'] >>> lst[2] = 3 # modification de la liste >>> tp = tuple(lst) # conversion en un tuple >>> tp # renvoie le tuple ('a', 2, 3, 7, 'b') </code> ====7. Fonction renvoyant un tuple ==== Les affectations multiples (§2) s'utilisent souvent dans les fonctions renvoyant un tuple. //Exemple// : calcul des longueurs des trois côtés d'un triangle. <code python *.py> from math import sert # Déclaration de la fonction def longueurs(A,B,C): xA,yA = A xB,yB = B xC,yC = C ďAB = sqrt((xB - xA)**2 + (yB- yA)**2) ďBC = sqrt((xC - xB)**2 + (yC- yB)**2) ďAC = sqrt((xC - xA)**2 + (yC- yA)**2) return dAB,dBC,dAC # Utilisation M = (3.4,7.8) N = (5,1.6) P = (-3.8,4.3) dMN, dNP, dMP = longueurs(M,N,P) dMN # renvoie 6.4031... </code> ====8. tuple unpacking ==== <callout type="tip" icon="true">L'affectation dans Python peut concerner plusieurs variables à la fois.</callout> //Exemple 1// <code python *.py> couple = (100, 'spam') gauche, droite = couple print('gauche:', gauche, 'droite:', droite) # résultat gauche: 100 droite: spam </code> //Exemple 2// <code python *.py> # membre droit: une liste liste = [1, 2, 3] # membre gauche : un tuple gauche, milieu, droit = liste print('gauche:', gauche, 'milieu:', milieu, 'droit:', droit) # gauche: 1 milieu: 2 droit: 3 </code> <callout icon="fa fa-hand-stop-o" color="red" title="STOP">Les seules contraintes fixées par Python sont que : \\ - le terme à droite du signe = soit un itérable (tuple, liste, string, etc.) ; \\ - le terme à gauche soit écrit comme un tuple ou une liste - notons tout de même que l'utilisation d'une liste à gauche est rare et peu pythonique ; \\ - les deux termes aient la même longueur - en tout cas avec les concepts que l'on a vus jusqu'ici, mais voir aussi plus bas l'utilisation de *arg avec le extended unpacking.</callout> //Exemple 3// <callout type="tip" icon="true">Il est possible de faire une boucle for qui itère sur une seule liste mais qui agit sur **plusieurs variables**.</callout> <code python *.py> entrees = [(1, 2), (3, 4), (5, 6)] for a, b in entrees: print(f"a={a} b={b}") ''' a=1 b=2 a=3 b=4 a=5 b=6 ''' </code> ====9. Extended unpacking==== <callout type="primary" icon="true">Le mécanisme ici est une extension de sequence unpacking ; Python vous autorise à mentionner une seule fois, parmi les variables qui apparaissent à gauche de l'affectation, une variable précédée de *.</callout> //Exemple 1// <code python *.py> reference = [1, 2, 3, 4, 5] a, *b, c = reference print(f"a={a} b={b} c={c}") # a=1 b=[2, 3, 4] c=5 </code> Cela peut s'avérer pratique, lorsque par exemple on s'intéresse seulement aux premiers éléments d'une structure : //Exemple 2// <code python *.py> # si on sait que data contient prenom, nom, # et un nombre inconnu d'autres informations data = [ 'Jean', 'Dupont', '061234567', '12', 'rue du four', '57000', 'METZ', ] # on peut utiliser la variable _ # ce n'est pas une variable spéciale dans le langage, # mais cela indique au lecteur que l'on ne va pas s'en servir prenom, nom, *_ = data print(f"prenom={prenom} nom={nom}") # résultat : prenom=Jean nom=Dupont </code> <callout type="info" icon="true">On peut utiliser plusieurs fois la même variable dans la partie gauche de l'affectation.</callout> Cette technique n'est utilisée en pratique que pour les parties de la structure dont on n'a que faire dans le contexte. Dans ces cas-là, il arrive qu'on utilise le nom de variable _. //Exemple 3// <code python *.py> entree = [1, 2, 3] # _, milieu, _ = entree print('milieu', milieu) # résultat : milieu 2 ignored, ignored, right = entree print('right', right) # résultat :right 3 </code> {{ :python:bases:realpython.png?nolink|}} ==== Quiz ==== * <html><a href="https://realpython.com/quizzes/python-lists-tuples/" target="_blank">Python List and Tuples Quiz</a></html> {{ :python:bases:realpython.png?nolink|}} ==== Pour aller plus loin ... ==== * <html><a href="https://realpython.com/python-namedtuple/" target="_blank">Write Pythonic and Clean Code With namedtuple</a></html> python/bases/tuples.txt Dernière modification : 2022/08/29 18:52de phil