Accueil

Traduction

Tutoriel Python - sommaire

Tutoriel Python - recherche

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

Approfondissements sur les structure itérables

Si vous avez lu tous les chapitres précédents vous avez déjà appris beaucoup de choses. Mais vous avez peut-être le sentiment de tout mélanger. Il est possible que vous soyez effrayé par les connaissances à retenir.
Je m'en vais vous rassurer. D'abord il ne faut pas tout apprendre par coeur ; c'est impossible, tant le langage Python est riche. Il suffit que vous disposiez de techniques pour retrouver rapidement l'information dont vous avez besoin.

Dans ce chapitre, je ne vais pas aborder de nouvelles notions mais simplement revenir mais en approfondissant, sur les structures itérables (chaines, listes, ensembles, dictionnaires, tuples).

Savoir utiliser la documentation

Structures itérables - définition

Un itérable est une structure de données qui peut être parcourue par une boucle FOR.
Les types itérables sont : str, list, tuple, dict, set.
On appelle séquence un itérable indexable : on peut associer à chaque élément un indice. Les chaines, listes & tuples sont des séquences mais pas les dictionnaires et les ensembles (ou 'set').
On dit aussi que les séquences sont "sliceables" (on peut extraire une tranche).

Découvrir les méthodes d'une classe

Entre les listes, les tuples, les dictionnaires, les ensembles vous êtes perdus. Quel type de séquence utiliser ???
Quelles méthodes puis-je employer à un ensemble. Sont-elles les mêmes que celles relatives à une liste ou un tuple ou encore un dictionnaire ???
Pour connaitre les méthodes d'une classe il suffit de taper dans la console de Python : dir(nomClasse) ou help(nomClasse)

Commande dir

Commandes à saisir dans l'interpréteur :

Ci-dessous, j'ai supprimé, des captures d'écran, les méthodes spéciales ou "magiques" : celles qui sont précédées et suivies de deux "underscores"). Nous n'avons pas à nous préoccuper pour l'instant.
Notez le nombre impressionnant de méthodes que l'on peut appliquer à une chaine (instance de la classe 'str'). Par contre les méthodes de la classe "tuple" ne sont qu'au nombre de 2 (index() & count()) et c'est logique puisque les tuples ne sont pas mutables.
Notez que certaines méthodes sont aussi communes à plusieurs classes. Ainsi on retrouve la méthode clear() pour les listes, les ensembles et les dictionnaires. La méthode count() est présenté dans plusieurs classes. On trouve également la méthode index() pour les classes "list", "tuple", "str" mais pas pour les dictionnaires et les ensembles qui ne sont pas des séries indexables.
Par contre l'ajout d'un élément se fait avec add() pour un 'set' alors qu'il se fait avec append() pour une liste.

Commande help

Pour avoir des infos plus détaillées sur la syntaxe et le rôle de chaque méthode de classe il est préférable d'utiliser la commande help.

Fonctions génériques et méthodes de classes

Je l'ai déjà signalé dans le chapitre 8, mais je pense qu'il pas inutile de faire une piqure de rappel : il ne faut pas confondre fonctions génériques (ou "builtin" ) avec méthodes de classe.
Par exemple, ne confondez pas : sort() et sorted() ; de même que reverse() et reversed().
sort() & reverse() sont de méthodes de la classe 'list' tandis que sorted() & reversed() sont des fonctions génériques qui peuvent donc s'appliquer à n'importe quelle séquence itérable (liste, tuple, dictionnaire, ensemble ou chaine).
Etudiez bien les commandes ci-dessous !

Moralité : employez plutôt les fonctions génériques que certaines méthodes de classe.

Cette différence de syntaxe découle de la POO (Programmation Orienté Objet ; pour les attributs et méthodes d'une classe il faut utiliser la notation pointée.

Retour sur les chaines (ou "strings")

L'image est grivoise mais le discours qui suit est des plus sérieux.

Je rappelle que dans un chapitre précédent, nous avons vu qu'il était facile de produire une chaine à partir d'une liste OU d'un tuple OU d'un dictionnaire OU d'un ensemble) via la méthode join(). Il est en effet, souvent plus simple de manipuler une chaine qu'une énumération d'éléments.

Quelques méthodes applicables aux chaines

Jusqu'à présent je n'ai présenté que quelques méthodes de la classe 'str' alors qu'elles sont très très nombreuses ...
Commençons :

Les méthodes lower(), upper(), capitalize() "modifient la casse".
Bien évidemment ces méthodes n'ont aucun impact sur des chaines composées de chiffres.

Davantage de méthodes

Petit à petit on découvre la richesse des méthodes applicables à une chaine.

Rechercher une sous-chaine dans une chaine

Pour réchercher un caractère (ou plusieurs) dans une chaine, vous pensez à index() mais il existe aussi find(), rindex() et rfind(), startswith(), endswidth() ainsi que les opérateurs "in" et "not in".
Attention la méthode find() n'existe que pour la classe "str".

Je rappelle aussi que la fonction search() du module "re" permet de vérifier si une chaine correspond (ou pas) à un certain gabarit (défini en utilisant la syntaxe des expressions régulières).

Effacer les espaces dans une chaine

Exemple :

lstrip() efface les espaces en début de chaine, rstrip() efface les espaces en fin de chaine ; strip() équivaut à lstrip().rstrip().
Pour effacer les espaces en milieu de chaine il faut utiliser de la façon suivante : replace(" " ."") (remplacer espace par rien).

Extraire une sous-chaine d'une chaine

Obtenir une chaine débarassée de symboles et espaces

Les méthodes strip(), lstrip() & lstrip() sans arguments effacent les espaces. Mais vous pouvez argumenter ces méthodes.

Exemple : on souhaite débarasser une chaine des espaces,étoiles et tirets.

Pour effacer des caractères parasites en milieu de de chaine l'astuce consiste à utiliser replace() avec en deuxième argument une chaine vide.
Exemple ci-dessous.

Le "slicing" ou tranchage

Le 'slicing" a déjà été évoqué. Une simple expression entre crochets dit beaucoup de choses. Aussi la compréhension de cette expression n'est pas toujours facile. Sachez que l'indice peut être une valeur négative afin d'extraire à partir de la fin (ou droite de la chaine).

Donc le cadre du "slicing", l'indice peut avoir une valeur négative ; ce qui veut dire : extraire à partir de la fin (ou de la droite).

Exemple : dans des chaines on trouve le mon d'une espèce animal, nom précédé OU suivi d'un code indiquant le groupe : "bi" comme bivalve ; "ga" comme gastéropode.
On veut afficher seulement le nom de l'espèce ; il faut donc pratiquer le "slicing" pour se débarasser du code-groupe.

On affiche uniquementn le nom de l'espèce.

Autre exemple de "tranchage" :
Rappelez vous, dans le chapitre 6 j'ai évoqué le code de César : un système de cryptage simple reposant sur un décalage de n lettres.

Grâce au "slicing" j'obtiens la table de conversion ("a" devient "c" , "b" devient "d" ... "z" devient "b") dans l'hypothèse d'un décalage de 2 (valeur de n).
Notez que - et c'est important en programmation - l'expression entre crochets peut contenir des variables.

Convertir les chaines en nombres

Voilà une problèmatique que vous allez rencontrer souvent en programmation Python.
En effet la fonction input() retourne toujours une donnée de type 'str' même si vous n'avez saisi que des chiffres.

Tapez les commandes suivantes dans la console Python :

La fonction int(chaine) convertit une chaine en entier si celle-ci ne contient qu'une suite de chiffres mais "plante" si le format de la chaine est celle d'un flottant.
La fonction eval(chaine) peut convertir une chaine en flottant (nombre décimal).
Donc pour convertir une chaine corrrespondant à un nombre décimal en un entier il faut imbriquer eval() dans int() !

Transformer une chaine en liste

Employer la fonction générique 'list' n'est pas la bonne solution : chaque caractère de la chaine devient un item de la liste.

Par contre la méthode split() produit une liste où chaque mot de la chaine d'origine devient un item de la liste.

Retour sur les listes

Je vais maintenant revenir sur les listes.

Rappels de méthodes applicables à un objet 'list'

Il s'agit ici d'une "piqure de rappel". Toutes ces méthodes ont déjà été évoquées dans des chapitres précédents.
Je signale qu'il existe aussi les méthodes extend() pour ajout N éléments en fin de liste et insert(position, valeur) pour insérer un élément au milieu d'une liste.

Produire un tuple ou ensemble à partir d'une liste

Il s'agit aussi de rappels.

Pour créer un objet 'tuple' à partir d'une liste il faut utiliser la fonction tuple()
Pour produire un ensemble à partir d'une liste il faut utiliser la fonction set()
Notez que la fonction set() est "intelligente" : produit bien un ensemble (pas de doublons même s'ils existe dans la série d'origine).

Retour sur les ensembles ou "set"

Quelques rappels et compléments concernant les ensembles.

Un ensemble est une structure "triable" mais pas réversible.
Un ensemble est itérable : peut être parcourue par un FOR.
Si vous tentez d'ajouter dans une séquence un élément qui existe déjà, il y a échec mais sans message d'erreur. Attention la syntaxe n'est pas "append" mais "add".
La méthode remove() peut s'appliquer à un ensemble mais il faut lui préférer la méthode discard() (pas de message éventuel d'erreur).
Pour terminer je vous montre qu'il est interdit de "slicer" un ensemble.
Je rappelle que concernant les ensembles il existe auss les opérations union & intersection qui ont déjà été abordées dans le chapitre 8. Je vous renvoie à ce chapitre : Tuto Python - chapitre 8

Retour sur les dictionnaires

Un dictionnaire (tableau associatif dans d'autres langages) est une structure qui comprend non pas des éléments mais des paires "clé : valeur" appelées items.

Un dictionnaire est une structure itérable mais la syntaxe de l'itération est un peu plus complexe que pour les autres types d'itérables.
Selon que vous voulez afficher les items (clé-valeur) OU seulement les clés OU seulement les valeurs il faut écrire : nomDict.items() / nomDict.keys() / nomDict.values avec "nomDict" : nom de la variable contenant le dictionnaire.

Annexe 1: méthodes de liste

Méthodes de liste

Dans cette annexe je présente de façon exhaustive toutes les méthodes d'un objet de type list.

Attention toutes ces méthodes modifient la liste d'origine. Les listes sont "muables".

Attention aux confusions

Pour supprimer un item d'une liste on peut aussi utiliser la fonction générique del().
Pour trier ou inverser, vous pouvez utiliser les fonctions natives sorted() & reversed() qui ne modifient pas la liste d'origine.
Vous pouvez aussi "slicer" une liste.

Exemple d'emploi de la fonction del() :

Le premier item a été supprimé.

Exemple d'emploi de sorted() et sort().

La fonction native sorted() ne modifie pas la liste d'origine, ce qui n'est pas le cas de la méthode de classe sort().
Je rappelle aussi que les syntaxes sont aussi différentes : fonctionNative(objet) d'une part et objet.méthode() d'autre part.

Annexe 2 : méthodes de chaine

Attention les chaines sont "immuables" : en appliquant une méthode à une chaine celle-ci n'est pas modifiée ; il faut affecter la modification à une nouvelle chaine.
Démonstration :

La chaine "machaine" n'a pas été modifiée par la méthode upper() mais une nouvelle chaine "machaine2" a été créée!

Pour rechercher une sous-chaine dans une chaine on peut utiliser index() mais aussi find() Cette dernière présente un gros avantage : si l'occurence n'est pas trouvée elle retourne -1 et non pas un message d'erreur. Elle est donc à priviligier en programmation.