Séquences : chaînes de caractères Définition de séquences. Opérations sur les séquences. Instruction for. Fonctions permettant de manipuler des chaînes de caractères. Comparaison de chaînes de caractères. Formatage. Exemples d’application. Une séquence est une suite d’éléments ordonnés séquentiellement et accessibles via des indices. Trois types de séquences : les chaînes de caractères, les listes, les tuples. Par exemple, une chaîne est une suite de caractères même si le type caractère n’existe pas de manière explicite en Python. Nous considérons d’abord tous les opérateurs et toutes les fonctions intégrées qui s’appliquent à toutes les séquences. Nous aborderons ensuite chaque type individuellement. 2 Opérateurs et fonctions intégrées applicables à toutes les séquences Une séquence est une suite d’éléments ordonnés où des indices permettent d’accéder à chaque élément. Ex.: "Une séquence" 0 1 2 U n e -12 -11 -10 3 -9 4 5 6 7 8 9 10 11 s é q u e n c e -8 -7 -6 -5 -4 -3 -2 -1 La longueur de la séquence est 12. Opérateurs sur les séquences : Priorité en ordre décroissant des opérateurs Soient s, s1, s2 des séquences, indice, indice1 et indice2 des positions d’éléments, s[indice] l’élément en position indice de la séquence s I s[indice1:indice2] une séquence renfermant dans le même ordre I les éléments de indice1 jusqu’à indice2 de s excluant l’élément en position indice2. s * expression entière une séquence obtenue en répétant s II « expression entière » fois. s1 + s2 une séquence obtenue en concaténant s1 avec s2. III element in s valeur booléenne indiquant si element appartient IV 3 element not in s à s ou non. IV Opérateur d’appartenance (in, not in) >>> # Calcul du nombre de voyelles dans un texte. >>> texte = "in retourne True si 'element' fait partie de s." >>> nombre_de_voyelles = 0 >>> i = 0 >>> while (i < len(texte)): if (texte[i] in "aeiouyAEIOUY"): nombre_de_voyelles += 1 i += 1 >>> print nombre_de_voyelles 17 Note : Avec in et not in, on peut tester aussi la présence d’une sous-chaîne dans une chaîne : >>> 'bc' in 'abcd' True Opérateur de concaténation (+) Soient s1 et s2 deux séquences de même type, s1 + s2 est la séquence obtenue en combinant les éléments de s1 avec ceux de s2 sans changer l’ordre et sans se soucier du fait que certains éléments puissent faire partie des 2 séquences s1 et s2. >>> print "La lettre e " + "se retrouve à plusieurs reprises dans cette phrase." 4 La lettre e se retrouve à plusieurs reprises dans cette phrase. Note : On peut aussi concaténer des chaînes comme suit : >>> texte = ("Il existe une autre syntaxe pratique pour les programmeurs. " "Cela permet de créer une seule chaîne à partir de plusieurs littéraux adjacents. " "Il n'est plus nécessaire d'utiliser le caractère \.") >>> print texte Il existe une autre syntaxe pratique pour les programmeurs. Cela permet de créer une seule chaîne à partir de plusieurs littéraux adjacents. Il n'est plus nécessaire d'utiliser le caractère \. Impossible de modifier une chaîne >>> Message = "ceci est une erreur." >>> Message[0] = 'C' Traceback (most recent call last): File "<pyshell#1>", line 1, in <module> Message[0] = 'C' TypeError: 'str' object does not support item assignment Mais on peut construire une nouvelle chaîne : >>> Message = "ceci est une erreur." >>> Message = "C" + Message[1:] >>> print Message 5 Ceci est une erreur. Opérateur de répétition (*) Cet opérateur permet de construire une nouvelle séquence en effectuant des copies consécutives des éléments d’une séquence. >>> s = "cher" >>> t = s * 2 >>> print s + " " + t cher chercher La variable d’origine s n’est pas modifiée. 6 Opérateurs de découpage ([ ], [ : ], [ : : ]) Extraction d’une sous-séquence dans une séquence s[m:n] désigne une séquence renfermant les éléments en position m, m+1, m+2, …, n-1 de la séquence s. m et n sont facultatifs. S’ils ne sont pas spécifiés ou si l’on utilise None comme indice, la tranche commencera au début de la séquence et/ou finira à la fin de celle-ci. Différence entre les indices positifs et négatifs : les premiers commencent au début de la séquence alors que les seconds fonctionnent à rebours à partir de la fin. La tentative d’extraire un élément de séquence avec un indice dépassant la longueur de la séquence génère une exception. >>> mot = "courageusement" >>> print mot[3:7] rage >>> print mot[:7] courage >>> print mot[10:] ment >>> print mot[:] courageusement >>> print mot[None:10] courageuse >>> print mot[:-7] courage >>> print mot[-11:-7] rage 7 s[m:n:p] désigne une séquence renfermant les éléments en position m, m+p, m+2p, …, m+kp de la séquence s, 1er cas: p > 0 2ième cas: p < 0 découpage de la gauche vers la droite k étant le plus grand entier où m+kp n. découpage de la droite vers la gauche k étant le plus petit entier où m+kp n. >>> mot = "locomotive" >>> print mot[::2] lcmtv >>> print mot[:6:] locomo >>> print mot[::2], mot[:6:], mot[::-1], mot[::-2] lcmtv locomo evitomocol eiooo >>> print mot[-2:-6:-1] vito >>> print mot[2:6:-1] >>> print mot[6:2:-1] tomo 8 Instruction for pour parcourir séquentiellement les éléments d’une séquence s 1ière approche : for membre in s: instruction instruction ... instruction À chaque itération, membre contient un élément de la séquence s; le bloc d’instructions est exécuté avec l’élément membre. Parcours d’une chaîne à l’aide de l’instruction for >>> mot = "pasta" >>> i = 0 >>> while i < len(mot): if mot[i] == "a" : print "e", else: print mot[i], i=i+1 peste >>> mot = "pasta" >>> for caractere in mot: if caractere == "a": print "e", ou encore else: print caractere, peste 9 Déterminer le nombre de voyelles dans une chaîne. >>> mot = "saperlipopette" >>> Nombre_de_voyelles = 0 >>> Voyelles = "aeiouyAEIOUY" >>> for caractere in mot : if (caractere in Voyelles): Nombre_de_voyelles = Nombre_de_voyelles + 1 >>> print Nombre_de_voyelles 6 2ième approche : for indice in range(len(s)): instruction instruction ... instruction À chaque itération, indice contient l’indice d’un élément de la séquence s; le bloc d’instructions est exécuté avec l’indice d’un membre. 10 Note : range(len(s)) désigne la liste des indices des éléments de s. >>> mot = "saperlipopette" >>> Nombre_de_voyelles = 0 >>> Voyelles = "aeiouyAEIOUY" >>> for indice in range(len(mot)): if (mot[indice] in Voyelles): Nombre_de_voyelles = Nombre_de_voyelles + 1 >>> print Nombre_de_voyelles 6 La fonction range() dispose de plusieurs syntaxes : range(fin) : retourne une liste de nombres de 0 jusqu’à fin - 1. range(debut, fin) : retourne une liste de nombres de debut jusqu’à fin - 1. range(debut, fin, pas) : >>> range(5) [0, 1, 2, 3, 4] >>> range(3, 8) [3, 4, 5, 6, 7] retourne une liste de nombres de debut jusqu’à fin – 1 par incréments de pas. >>> range(3, 13, 4) [3, 7, 11] 11 3ième approche : On peut aussi parcourir séquentiellement une séquence s par élément et par indice. for indice, membre in enumerate(s): instruction instruction ... instruction À chaque itération, indice et membre réfèrent à un élément de la séquence s; le bloc d’instructions est exécuté avec l’élément membre et l’indice de ce membre. >>> mot = "saperlipopette" >>> Nombre_de_voyelles = 0 >>> Voyelles = "aeiouyAEIOUY" >>> for indice, caractere in enumerate(mot): if (caractere in Voyelles): Nombre_de_voyelles = Nombre_de_voyelles + 1 print indice, caractere 1a 3e 6i 8o 10 e 13 e >>> print Nombre_de_voyelles 6 12 Instructions break, continue et else avec l’instruction for break Met fin à la boucle courante et reprend l’exécution à l’instruction suivante. >>> n = input("Entrez un nombre entier : ") Entrez un nombre entier : 26 >>> v = n / 2 >>> for i in range(v, 0, -1): if (n % i == 0): print i, " est le plus grand diviseur de ", n break 13 est le plus grand diviseur de 26 continue Déterminer s’il reste des arguments à parcourir et poursuivez à l’itération suivante le cas échéant. else Dans une boucle, une clause else ne sera exécutée que si elle se termine normalement, autrement dit, si elle n’a pas été abandonnée par un break. 13 else Dans une boucle, une clause else ne sera exécutée que si elle se termine normalement, autrement dit, si elle n’a pas été abandonnée par un break. >>> n = input("Entrez un entier positif : ") Entrez un entier positif : 12 >>> for i in range(n): print i+1 else: print n * (n + 1) / 2 1 2 3 4 5 6 7 8 9 10 11 12 78 14 Comparaison de chaînes de caractères Les opérateurs de comparaison ==, !=, >, <, >=, <= sont définis sur des chaînes de caractères. >>> mot = "Tom" >>> if (mot != "tom"): if(mot > "Timothy"): print mot else: print "*** ERREUR ***" Tom Les chaînes sont comparées dans l’ordre lexicographique (selon les valeurs ASCII). >>> cmp("Pierre", "Luc") 1 >>> cmp("Jos", "Louis") -1 >>> cmp("Ouf", "Ouf") 0 >>> cmp("","aed") -1 >>> cmp(" AED", "BC") -1 >>> cmp(" a", "bb") -1 >>> cmp(" ","a") -1 15 Précédence lexicographique des chaînes de caractères Cette relation de précédence suit l’ordre du dictionnaire et est définie de façon récurrente comme suit : Ex. : Ex. : >>> print 9 - int("0") 9 >>> print type(9 - int("0")) <type 'int'> 16 Il est facile de convertir des lettres majuscules en minuscules : if (C >= 'A' and C <= 'Z'): C = chr(ord(C) - ord("A") + ord("a")) if (C >= 'a' and C <= "z"): C = chr(ord(C) - ord("a") + ord("A")) lower() : convertit une chaîne en minuscules >>> c = "AbraCadABRA" >>> print c.lower() abracadabra count(sch) : compte le nombre de sous-chaînes sch dans la chaîne. >>> message = "Elle ne doit pas jouer au ballon dans le salon." >>> print message.count("lon") 2 len(c) : retourne la longueur de la chaîne de caractères c. >>> message = "Elle ne doit pas jouer au ballon dans le salon." >>> print len(message) 47 max(c) ou min(c) : retourne le plus grand(petit) caractère de la chaîne c. >>> print min("bibliothèque"), max("livre") bv 17 reversed(s) : permet de parcourir les éléments de la séquence s en sens inverse. >>> texte = "abracadabra" >>> for caractere in reversed(texte): print caractere, arbadacarba find(sch) : cherche la position d’une sous-chaîne sch dans la chaîne en débutant la recherche à partir du début. rfind(sch) : idem sauf que la recherche débute à partir de la fin. >>> message = "Je ne peux entendre un traitre mot à cause du bruit de la locomotive." >>> print message.find("mot") 31 >>> print message[32:].find("mot") 30 >>> mot = "saperlipopette" >>> print mot.rfind("pe") 18 9 split() : convertit une chaîne en une liste de sous-chaînes à partir d’un séparateur (l’espace par défaut). >>> message = "Je suis entouré d'espaces. Signé : un mot." >>> print message.split() ['Je', 'suis', 'entouré', "d'espaces.", 'Signé', ':', 'un', 'mot.'] >>> print message.split(".") ["Je suis entouré d'espaces", ' Signé : un mot', ''] join(liste) : rassemble une liste de chaînes en une seule. La chaîne à laquelle on applique cette méthode servira de séparateur tandis que l’argument transmis est la liste des chaînes à rassembler. >>> liste = ["Le ciel est bleu.", "La vie est belle.", "Vive les vacances."] >>> " ".join(liste) 'Le ciel est bleu. La vie est belle. Vive les vacances.' >>> print "**".join(liste) Le ciel est bleu.**La vie est belle.**Vive les vacances. upper() : convertit une chaîne en majuscules. >>> message = "Le toit s'effondre. " + "Au secours.".upper() >>> print message Le toit s'effondre. AU SECOURS. 19 capitalize() : convertit la première lettre d’une chaîne en majuscule. swapcase() : convertit toutes les majuscules en minuscules et vice-versa. strip() : enlève les espaces éventuels au début et à la fin d’une chaîne. replace(c1, c2) : remplace tous les caractères c1 par des caractères c2 dans la chaîne. >>> message = "Je suis fâché de la situation; je dirais même plus, je suis très fâché." >>> print message.replace("fâch", "outr") Je suis outré de la situation; je dirais même plus, je suis très outré. index(sch) : rindex(sch) : retrouve l’index de la première occurrence de la sous-chaîne sch dans la chaîne en débutant la recherche à partir du début (en position 0 ou en position 3). idem sauf que la recherche débute à partir de la fin. >>> message = "oui, ce cours est terminé pour toujours." >>> print message.index("e") 6 >>> print message.rindex("e") 19 >>> print message.index("ou", 3) 9 >>> print message.rindex("ou", 3) 35 20 Conversion en chaînes de caractères >>> n = 12 >>> n, str(n) (12, '12') Formatage des chaînes de caractères Vous construisez une chaîne à l’aide d’une chaîne de formatage qui contient des marqueurs de conversion, et une liste entre parenthèses d’objets à insérer dans la chaîne, en lieu et place des marqueurs. Il existe différents marqueurs de conversion comme par exemple : %s : accepte n’importe quel objet (chaîne, entier, réel, …), %d : accepte un entier, %8.2f ou %8.2g : accepte un réel avec une largeur et une précision. >>> n = 3 >>> equipe = "les bagarreurs" >>> print "Pierre est le numéro %s au soccer. Son équipe s'appelle %s." % (n, equipe) Pierre est le numéro 3 au soccer. Son équipe s'appelle les bagarreurs. >>> print "Ce nombre est : %d." % (12) Ce nombre est : 12. >>> print "Ce nombre est : %4.2f." % (3.345) Ce nombre est : 3.35. >>> print "Ce nombre est : %4.2g." % (3.345) 21 Ce nombre est : 3.3. Les chaînes converties peuvent être utilisées en conjonction avec l’instruction print ou sauvegardées dans une nouvelle chaîne. D’autres directives …. >>> print "Ce nombre est : %8.2g." % (3.345) Ce nombre est : 3.3. >>> print "Ce nombre est : %+-8.2g." % (3.345) Ce nombre est : +3.3 . Aligner à gauche. Utiliser le signe + pour les nombres positifs. >>> print "Ce nombre est : %0+-8.2g." % (3.345) Ce nombre est : +3.3 . >>> print "Ce nombre est : %0+8.2g." % (3.345) Ce nombre est : +00003.3. >>> print "Ce nombre est : %08.2g." % (3.345) Ce nombre est : 000003.3. Remplir avec des zéros au lieu d’espaces. 22 Chaînes de caractères prédéfinies >>> import string >>> string.ascii_letters 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' >>> string.ascii_lowercase 'abcdefghijklmnopqrstuvwxyz' >>> string.ascii_uppercase 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' >>> string.digits '0123456789' >>> string.hexdigits '0123456789abcdefABCDEF' >>> string.letters 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\x83\x8a\x8c\x8e \x9a\x9c\x9e\x9f\xaa\xb5\xba\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd \xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3 \xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa \xfb\xfc\xfd\xfe\xff' >>> string.octdigits '01234567' >>> string.punctuation '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' >>> string.printable '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$ %&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c' 23 Exemple : Vérification si un identificateur est valide. import string alphas = string.ascii_letters + "_" entree = raw_input("Identificateur à tester : ") longueur = len(entree) if (longueur == 0): print "invalide" elif (longueur == 1): if (entree[0] in string.ascii_letters): print "valide" else : print "invalide" else: if (entree[0] not in alphas): print "invalide" else: for caractere in entree[1:]: if (caractere not in alphas + string.digits): print "invalide" break else: print "valide" À évaluer une seule fois. Note: raw_input() permet d’afficher la chaîne de caractères passée en paramètre et de lire une donnée laquelle renvoie toujours une chaîne de caractères. L’application ne prend pas en compte les mots-clés de Python qui sont des mots réservés et ne peuvent pas servir à nommer des identificateurs. 24 Remplacement des espaces par un seul espace dans une chaîne de caractères >>> # Ce programme prend en entrée une chaîne de caractères, >>> # construit une chaîne de caractères où chaque série d'espaces >>> # est remplacée par un seul espace, et affiche la nouvelle chaîne. >>> >>> c = raw_input("Entrez une chaîne : ") Entrez une chaîne : Voici un exemple de manipulation de chaînes de >>> pred = "c" >>> resultat = "" >>> for caractere in c: if (caractere != " " or (pred != " " and caractere == " ")): resultat += caractere pred = caractere caractères. >>> print resultat Voici un exemple de manipulation de chaînes de caractères. 25 Longueur moyenne d’un mot dans un texte >>> # Ce programme prend en entrée un texte, >>> # calcule la longueur moyenne d'un mot dans le texte et >>> # affiche ce résultat. >>> >>> texte = input("Entrez au clavier le texte : ") Entrez au clavier le texte : "Je suis emballé par ce programme." >>> L = len(texte) >>> i = 0 >>> while (i < len(texte)): if(texte[i] == " "): L = L - 1 i=i+1 >>> print "Longueur moyenne d'un mot : %5.2f" % (L / (len(texte) - L + 1.0)) Longueur moyenne d'un mot : 4.67 26 Conjugaison d’un verbe régulier en « er » au présent de l’indicatif >>> # Ce programme prend en entrée un verbe régulier en «er» au clavier et >>> # affiche la conjugaison au présent de l'indicatif. >>> >>> verbe = input("Entrez le verbe à conjuguer : ") Entrez le verbe à conjuguer : "aimer" >>> v = verbe[0:len(verbe) - 2] >>> if (v[0] in "aeiouy"): conjugaison = "J'%se\n" % (v) else : conjugaison = "Je %se\n" % (v) >>> conjugaison += "Tu %ses\n" % (v) >>> conjugaison += "Il %se\n" % (v) >>> conjugaison += "Nous %sons\n" % (v) >>> conjugaison += "Vous %sez\n" % (v) >>> conjugaison += "Ils %sent\n" % (v) >>> print conjugaison J'aime Tu aimes Il aime Nous aimons Vous aimez Ils aiment 27 Fréquence des caractères d’un texte # Construire un programme qui affiche la fréquence de chaque caractère # faisant partie d’un texte. texte = ("Et en effet, sur la planete du petit prince, il y avait comme sur toutes les " "planetes, de bonnes herbes et de mauvaises herbes. Par consequent, de " "bonnes graines de bonnes herbes et de mauvaises graines de mauvaises" " herbes. Mais les graines sont invisibles. Elles dorment dans le secret de " "la terre jusqu'a ce qu'il prenne fantaisie a l'une d'elles de se reveiller.") # Le Petit Prince, # A. de Saint-Exupéry # Déterminer tous les caractères faisant partie du texte à l'étude. ensemble_des_caracteres = "" for caractere in texte: if (caractere not in ensemble_des_caracteres): ensemble_des_caracteres += caractere ensemble_des_caracteres = sorted(ensemble_des_caracteres) # Calcul de la fréquence de chaque caractère et affichage des résultats. print "Fréquence de chaque caractère faisant partie du texte :\n\n" for caractere in ensemble_des_caracteres: print "Fréquence du caractère %s : %d" %(caractere, texte.count(caractere)) Fréquence de chaque caractère faisant partie du texte : Fréquence du caractère : 62 Fréquence du caractère ' : 4 Fréquence du caractère , : 4 Fréquence du caractère . : 4 Fréquence du caractère E : 2 Fréquence du caractère M : 1 Fréquence du caractère P : 1 Fréquence du caractère a : 22 Fréquence du caractère b : 8 Fréquence du caractère c : 5 Fréquence du caractère d : 12 Fréquence du caractère e : 61 Fréquence du caractère f : 3 Fréquence du caractère g : 3 Fréquence du caractère h : 4 Fréquence du caractère i : 18 Fréquence du caractère j : 1 Fréquence du caractère l : 17 Fréquence du caractère m : 6 Fréquence du caractère n : 23 Fréquence du caractère o : 8 Fréquence du caractère p : 5 Fréquence du caractère q : 3 Fréquence du caractère r : 18 Fréquence du caractère s : 34 Fréquence du caractère t : 17 Fréquence du caractère u : 12 Fréquence du caractère v : 6 Fréquence du caractère y : 1 29 Suppression d’une sous-chaîne # # # # Construire un programme qui supprime n caractères d’une chaîne à partir de la position p. p doit être compris entre 0 et le nombre de caractères de la chaîne -1. Dans le cas où n > longueur de la sous-chaîne débutant à p, supprimez uniquement cette sous-chaîne. chaine = input("Saisir la chaine au clavier : ") n = input("Entrez le nombre n de caracteres a supprimer : ") p = input("Entrez la position du premier caractere a supprimer : ") chaine = chaine[0:p] + chaine[p+n:] print chaine 30