• Aucun résultat trouvé

2Indiçage,extraction,longueurd’unechaîne 1Notiondechaînedecaractères Cours_Les_chaines_de_caract?res

N/A
N/A
Protected

Academic year: 2022

Partager "2Indiçage,extraction,longueurd’unechaîne 1Notiondechaînedecaractères Cours_Les_chaines_de_caract?res"

Copied!
16
0
0

Texte intégral

(1)

Cours_Les_chaines_de_caract?res

August 25, 2019

Enseignement de spécialité > 1ère NSI > PYTHON > Les structures conditionnelles David LATOUCHE - Cédric GERLAND - Lycée Saint-Exupéry

1 Notion de chaîne de caractères

Les chaînes de caractères font partie d’une catégorie d’objets Python que l’on appelle des séquences, et dont font partie aussi les listes et lestuples que nous étudierons plus tard. Les chaînes de caractèresconstituent un type dedonnée compositepouvant être vue tantôt comme une entitée globale bien définie mais qui est elle même un assemblage d’un ensemble d’entités plus petites appeléescaractères. Suivant les circonstances, nous serons amenés à traiter une telle donnée composite, tantôt comme un seul objet, tantôt comme une suite ordonnée d’éléments.

Dans ce dernier cas il nous faudra accéder à chacun de ces éléments à titre individuel.

2 Indiçage, extraction, longueur d’une chaîne

Les chaînes sont des séquences de caractères. Chacun de ceux-ci occupe une place précise dans la séquence. Sous Python, les éléments d ’une séquence sont toujours indicés (ou numérotés) de la même manière, c ’est-à-dire à partir de zéro . Pour extraire un caractère d ’une chaîne, il suffit d

’accoler au nom de la variable qui contient cette chaîne, son indice entre crochets : [1]: ville="Paris"

print(ville[0],ville[1],ville[2],ville[3],ville[4])

P a r i s

Il est souvent utile de pouvoir désigner l’emplacement d’un caractère par rapport à la fin de la chaîne. Pour ce faire, il suffit d’utiliser des indices négatifs : ainsi -1 désignera le dernier caractère, -2 l’avant-dernier, etc. :

[2]: print(ville[-1],ville[-2],ville[-3],ville[-4],ville[-5])

s i r a P

Si l ’on désire déterminer le nombre de caractères présents dans une chaîne, on utilise la fonc- tion intégréelen():

[3]: print(len(ville))

(2)

5

On peut parcourir individuellement les éléments d’une chaîne de caractères avec une boucle for:

[4]: chef_avengers = "Captain America"

for car in chef_avengers : print(car)

C a p t a i n A m e r i c a

3 Extraction de fragments de chaîne (slicing)

Il arrive fréquemment, lorsque l’on travaille avec des chaînes, que l’on souhaite extraire une petite chaîne d’une chaîne plus longue. Python propose pour cela une technique simple que l’on appelle slicing (découpage en tranches ). Elle consiste à indiquer entre crochets les indices correspondant au début et à la fin de la tranche que l’on souhaite extraire :

[5]: nom = "Laure Dinateur"

print(nom[0:5])

print(nom[6:len(nom)+1]) print(nom[0:8])

Laure Dinateur Laure Di

Dans la tranche [n,m] , le n ième caractère est inclus, mais pas le m ième .

Les indices de découpage ont des valeurs par défaut : un premier indice non défini est consid- éré comme zéro, tandis que le second indice omis prend par défaut la taille de la chaîne complète :

[6]: print(nom[:5]) # Les 5 premiers caractères (indices : 0 --> 4) print(nom[6:]) # Tout ce qui suit les 6 premiers caractères Laure

(3)

4 Concaténation, répétition de chaînes

Les chaînes peuvent être concaténées avec l ’opérateur + et répétées avec l ’opérateur * : [7]: prenom = "Steve"

nom = "Rogers"

alias = prenom + " " + nom print(alias)

print("Hip hip hip hourra !\t"*3)

Steve Rogers

Hip hip hip hourra ! Hip hip hip hourra ! Hip hip hip hourra !

5 Parcours d’une chaîne

Il arrive très souvent que l’on soit amené à traiter l’intégralité d’une chaîne, caractère par caractère, du premier jusqu’au dernier, pour effectuer à partir de chacun d’eux une opération quelconque.

Cette opération s’appelle un parcours . 5.1 Avec une boucle while

Nous pouvons envisager d’encoder un tel parcours à l’aide d’une boucle, articulée autour de l’instructionwhile:

[8]: chef_avengers = "Captain America"

indice = 0

while indice < len(chef_avengers):

print(chef_avengers[indice]) indice=indice+1

print("\nFin du programme")

C a p t a i n A m e r i c a

Fin du programme

(4)

[9]: chef_avengers = "Captain America"

indice = 0

while indice < len(chef_avengers):

print(chef_avengers[indice]) indice=indice+1

print("\nFin du programme")

C a p t a i n A m e r i c a

Fin du programme

Cette boucle parcourt donc la chaînechef_avengerspour en extraire un à un tous les caractères, lesquels sont ensuite affichés (notez les deux techinques d’affichage en lignes ou en colonnes).

Remarquez bien que la condition utilisée avec l’instruction while estindice < len(chef_avengers), ce qui signifie que le bouclage doit s’effectuer jusqu’à ce que l’on soit arrivé à l’indice numéro 14 (la chaîne compte en effet 15 caractères espace compris). Nous aurons effectivement traité tous les caractères de la chaîne, puisque ceux-ci sont indicés de 0 à 14.

5.2 Avec une boucle for ... in ...

Le parcours d’une séquence est une opération très fréquente en programmation. Pour en faciliter la mise en oeuvre, Python vous propose une structure de boucle plus appropriée que la boucle while, basée sur le couple d’instructions for ... in ... :

[10]: chef_avengers = "Captain America"

for car in chef_avengers : print(car)

C a p t

(5)

i n A m e r i c a

[11]: chef_avengers = "Captain America"

for car in chef_avengers : print(car)

C a p t a i n A m e r i c a

Comme vous pouvez le constater, cette structure de boucle est plus compacte. Elle vous évite en outre d’avoir à définir et à incrémenter une variable spécifique (un ´n compteur ˙z) pour gérer l’indice du caractère que vous voulez traiter à chaque itération (c’est Python qui s’en charge au- tomatiquement à votre place). Dans la structurefor ... in ... la variablecarcontiendra successive- ment tous les caractères de la chaîne, du premier jusqu’au dernier. Nous verrons prochainement que cette structure composée for ... in ... nous sera très utile pour le parcours des listes notamment.

6 Appartenance d’un élément à une chaîne : opérateur logique in

L’instructioninpeut être utilisée indépendamment defor, pour vérifier si un élément donné fait partie ou non d’une séquence. Il s’agit dans ce cas d’un opérateur logique. Vous pouvez par exemple vous servir deinpour vérifier si tel caractère alphabétique fait partie d’un groupe bien déterminé :

[12]: car = input("Entrez une lettre : ") voyelles = "aeiouyAEIOUY"

consonnes = "bcdfghjklmnpqrstvwxzBCDFGHJKLMNPQRSTVWXZ"

(6)

if car in voyelles :

print(car, "est une voyelle") elif car in consonnes :

print(car, "est une consonne") else :

print(car, "est un chiffre ou un caractère spécial") print("Fin du programme")

Entrez une lettre : Y Y est une voyelle Fin du programme

7 Conversion des chaînes de caractères

Il existe de nombreuses méthodes permettant de réaliser des opérations sur les chaînes de carac- tères. Quelques exemples d’utilisation des ce méthodes sont donnés ci-après :

7.1 Méthodes lower() et upper()

lower() :renvoie une copie d’une chaîne avec toutes les lettres converties en minuscules.

upper() :renvoie une copie d’une chaîne avec toutes les lettres converties en majuscules.

[13]: mot = "Bonjour"

mot1 = mot.lower() mot2 = mot.upper() print(mot1, mot2)

bonjour BONJOUR

7.2 Méthode swapcase()

swapcase(): renvoie une copie d’une chaîne dans laquelle les lettres minuscules sont conver- ties en majuscules et les lettres en majuscules sont converties en minuscules.

[14]: mot3 = "National Aeronautics and Space Administration"

print(mot3)

mot4 = mot3.swapcase() print(mot4)

National Aeronautics and Space Administration nATIONAL aERONAUTICS AND sPACE aDMINISTRATION 7.3 Méthode title()

title(): renvoie une copie d’une chaîne avec la première lettre en majuscule dans chaque mot.

(7)

[15]: mot5 = "national aeronautics and space administration"

print(mot5)

mot6 = mot5.title() print(mot6)

national aeronautics and space administration National Aeronautics And Space Administration 7.4 Méthode capitalize()

[16]: mot7 = "NASA"

print(mot7)

mot8 = mot7.capitalize() print(mot8)

NASA Nasa

7.5 Méthode replace()

replace(old, new) : retourne une nouvelle chaîne qui remplace toutes les occurrences de la chaîneoldpar la chaînenew.

[40]: supporter = "Mon joueur de foot préféré est Mbappé"

print(supporter)

supporter = supporter.replace("Mbappé","Griezmann") print(supporter)

Mon joueur de foot préféré est Mbappé Mon joueur de foot préféré est Griezmann 7.6 Elimination des espaces blancs

Vous pouvez utiliser les méthodes de la table suivante pour supprimer les caractères d’espacement de l’extrémité gauche, droite, ou les deux d’une chaîne de caractères :

lstrip(): retourne une chaîne avec les caractères blancs en début enlevés.

rstrip(): retourne une chaîne avec les caractères blancs à droite supprimés.

strip(): retourne une chaîne sans caractères blancs à gauche et droite.

Voici quelques exemples d’utilisation des méthodes ci-dessus : [18]: phrase1 = "Bienvenue John Snow\n"

phrase2 = "à la garde de nuit !"

print(phrase1) print(phrase2)

(8)

Bienvenue John Snow à la garde de nuit !

[19]: phrase1 = phrase1.rstrip() print(phrase1)

print(phrase2)

Bienvenue John Snow à la garde de nuit !

[20]: phrase3 = "Bienvenue John Snow"

phrase4 = "\nà la garde de nuit !"

print(phrase3) print(phrase4)

Bienvenue John Snow à la garde de nuit !

[21]: phrase4 = phrase4.lstrip() print(phrase3)

print(phrase4)

Bienvenue John Snow à la garde de nuit !

[22]: phrase5 = "Première phrase"

phrase6 = "\nDeuxième phrase\n"

phrase7 = "Troisième phrase"

print(phrase5) print(phrase6) print(phrase7)

Première phrase Deuxième phrase Troisième phrase

[23]: phrase6 = phrase6.strip() print(phrase5)

print(phrase6) print(phrase7)

(9)

Première phrase Deuxième phrase Troisième phrase

Les méthodes d’élimination des espaces blancs suppriment seulement les caractères blancs au début et à la fin d’une chaîne. Cependant, les caractères blancs entourés par des caractères non-blancs ne sont pas enlevés.

8 Recherche de sous-chaînes

Vous pouvez rechercher une chaîne dans une autre chaîne en utilisant les méthodes suivantes:

- endswith(sous_chaine) : renvoie True si la chaîne se termine par la sous-chaîne sous_chaine. - startswith(sous_chaine) : renvoie True si la chaîne commence par la sous-chaîne sous_chaine. - find(sous_chaine) : retourne l’indice le plus bas oùsous_chaine commence dans cette chaîne, ou - 1 si sous_chaine ne se trouve pas dans cette chaîne. -rfind(sous_chaine) : renvoie l’indice le plus élevé oùsous_chainecommence dans cette chaîne, ou -1 sisous_chainene se trouve pas dans cette chaîne. -count(sous_chaine): renvoie le nombre d’occurrences desous_chaine.

Voici ci-après quelques exemples d’utilisation des méthodes exposées ci-dessus:

[24]: bienvenue = "Welcome to Python"

print(bienvenue.endswith("thon"))

print(bienvenue.startswith("Bienvenue")) print(bienvenue.find("come"))

print(bienvenue.find("become")) print(bienvenue.rfind("o")) print(bienvenue.count("o"))

True False 3 -1 15 3

9 Propriétés fondamentales des chaînes

9.1 Les chaînes sont des séquences non modifiables

On ne peut pas modifier le contenu d’une chaîne existante. En d’autres termes, vous ne pouvez pas utiliser l’opérateur [ ] dans la partie gauche d’une instruction d’affectation. Essayons par exemple d’exécuter le petit script suivant (qui cherche intuitivement à remplacer une lettre dans une chaîne) :

[ ]: salut = 'bonjour à tous' salut[0] = 'B'

print(salut)

Le résultat attendu ´nBonjour à tous ˙z (avec un B majuscule) n’est pas obtenu ! En effet le script lève une erreur du genre : TypeError: str object does not support item assignment. Cette erreur est

(10)

provoquée à la deuxième ligne du script où on essaie de remplacer une lettre par une autre dans la chaîne. Les chaînes de caractères sont des objets non modifiables. Nous verrons prochainement que les objets de typelistpourront quant à eux être modifiés.

Par contre, le script ci-dessous fonctionne parfaitement : [25]: salut = 'bonjour à tous'

salut = 'B' + salut[1:]

print(salut)

Bonjour à tous

Dans l’exemple ci-dessus, nous ne modifions pas la chaînesalut. En effet, nous en re-créons une nouvelle, avec le même nom, à la deuxième ligne du script (à partir d’un morceau de la précédente, soit, mais qu’importe : il s’agit bien d’une nouvelle chaîne).

9.2 Les chaînes sont comparables

Tous les opérateurs de comparaison dont nous avons parlé à propos des instructions de contrôle de flux (c’est-à-dire les instructions if ... elif ... else ) fonctionnent aussi avec les chaînes de carac- tères. Cela peut vous être utile pour trier des mots par ordre alphabétique par exemple :

[26]: while True:

mot = input("Entrez un mot quelconque en minuscules non accentuée : (<enter>␣

,pour terminer)") if mot =="":

break

if mot < "limonade":

place = "précède"

elif mot > "limonade":

place = "suit"

else:

place = "se confond avec"

print("Le mot {} {} le mot 'limonade' dans l'ordre alphabétique".

,format(mot,place))

Entrez un mot quelconque en minuscules non accentuée : (<enter> pour terminer)ordinateur

Le mot ordinateur suit le mot 'limonade' dans l'ordre alphabétique Entrez un mot quelconque en minuscules non accentuée : (<enter> pour terminer)ram

Le mot ram suit le mot 'limonade' dans l'ordre alphabétique

Entrez un mot quelconque en minuscules non accentuée : (<enter> pour terminer) Les comparaisons sont possibles, parce que dans toutes les normes d’encodage, les codes numériques représentant les caractères ont été attribués dans l’ordre alphabétique, tout au moins pour les caractères non accentués. Dans le système de codage ASCII, par exemple, A=65, B=66, C=67, etc.

(11)

Comprenez cependant que cela ne fonctionne bien que pour des mots qui sont tous entière- ment en minuscules, ou entièrement en majuscules, et qui ne comportent aucun caractère accen- tué. Vous savez en effet que les majuscules et minuscules utilisent des ensembles de codes dis- tincts. Quant aux caractères accentués, vous avez vu qu’ils sont encodés en dehors de l’ensemble constitué par les caractères du standard ASCII. Construire un algorithme de tri alphabétique qui prenne en compte à la fois la casse des caractères et tous leurs accents n’est donc pas une mince affaire !

10 Codage des caractères

10.1 Afficher la valeur en base décimale d’un caractère : la fonction ord()

La fonctionord()renvoie la valeur en base 10 associée à un caractère dans la norme ASCII (table de caractères non accentués) ou dans la norme Unicode (table de caractères accentués).

[27]: print(ord("a")) print(ord("A"))

97 65

On peut connaître toutes les valeurs des caractères d’une chaîne en parcourant celle-ci à l’aide d’une simple bouclefor.

[28]: chaine1="Bonjour !"

for car in chaine1 : print(ord(car))

66 111 110 106 111 117 114 32 33

Remarque : une fois la conversion d’un caractère en base 10 efectuée, il est facile d’exprimer sa valeur en base 16 et 2.

[29]: car = "à"

car_10 = ord(car) car_16 = hex(car_10) car_2 = bin(car_10)

print("{} : {} (base 10) ; {} (base 16) ; {} (base 2)".

,format(car,car_10,car_16,car_2) )

à : 224 (base 10) ; 0xe0 (base 16) ; 0b11100000 (base 2)

(12)

Remarque : la table ASCII est composée de 128 caractères non accentués dont les valeur en base 10 sont comprises entre 0 et 127. Les caractères accentués ou spéciaux non présents dans la table ASCII sont quant à eux codés en Unicode avec une valeur en base 10 supérieure à 128. La table des caractères Unicode inclue celle des caractères ASCII.

10.2 Afficher le caractère associé à une valeur en base décimale : la fonction chr() La fonctionchr(), inverse deord(), renvoie le caractère associé à un nombre en base 10.

[30]: print(chr(66),chr(111),chr(110),chr(106),chr(111),chr(117),chr(114),chr(32),chr(33))

B o n j o u r !

10.3 Codage / décodage d’une chaîne de caractères : ASCII et UTF-8 10.3.1 La méthode encode()

La méthodeencode()permet d’encoder une chaîne de caractères dans un format spécifique (ASCII ou UTF8 par exemple).

[31]: message1 = "Salut tout le monde !"

print(message1.encode('ascii'))

b'Salut tout le monde !'

L’encodage ASCII d’un message comportant des caractères accentués conduit à un message d’erreur.

[32]: message2 = "Es-tu sûr d'être habillé de cette façon pour aller à cette soirée ?"

print(message2.encode('ascii'))

,--- UnicodeEncodeError Traceback (most recent call␣

,last)

<ipython-input-32-bce2ab0c4652> in <module>

1 message2 = "Es-tu sûr d'être habillé de cette façon pour aller à␣

,cette soirée ?"

----> 2 print(message2.encode('ascii'))

UnicodeEncodeError: 'ascii' codec can't encode character '\xfb' in␣

,position 7: ordinal not in range(128)

Il faut donc passer en encodage UTF8 pour résoudre le problème :

(13)

[33]: message2_octets = message2.encode('utf-8') print(message2_octets)

b"Es-tu s\xc3\xbbr d'\xc3\xaatre habill\xc3\xa9 de cette fa\xc3\xa7on pour aller

\xc3\xa0 cette soir\xc3\xa9e ?"

En procédant ainsi, nous ne récupérons donc pas la chaîne de caractères initiale, mais bien sa traduction concrète en octets, dans une donnée de typebytes. Lorqu’on lui demande d’afficher une donnée de typebytesà l’aide la fonctionprint(), Python nous en fournit en fait une représentation, entre deux apostrophes pour indiquer qu’il s’agit d’une chaîne, mais celles-ci précédées d’unb minuscule pour spécifier qu’il s’agit d’une chaîne d’octets (bytes), avec les conventions suivantes :

• Les octets de valeur numérique comprise entre 32 et 127 sont représentés par le caractère correspondant du code ASCII.

• Certains octets de valeur numérique inférieure à 32 sont représentés de manière convention- nelle, comme par exemple le caractère de fin de ligne.

• Les autres octets sont représentés par leur valeur hexadécimale, précédée deantislah x.

Dans le cas de notre exemple, on voit que les caractères non accentués de la chaîne utilisée ont été encodés chacun à l’aide d’un seul octet correspondant à son code ASCII : nous les reconnais- sons donc directement. Les caractères accentués, par contre (ils n’existent pas dans le code ASCII), sont encodés chacun sur deux octets. Cette forme particulière d’encodage correspond à la norme UTF-8.

La représentation obtenue avecprint()nous aide à reconnaître notre chaîne initiale, certes, mais elle ne nous montre pas assez bien qu’il s’agit en fait d’octets. Nous avons vu précédemment que l’on pouvait aussi examiner le contenu d’une séquence, élément par élément, à l’aide d’une boucle de parcours. Voyons ce que cela donne ici :

[34]: for car in message2_octets:

print(car)

print("\nFin du programme")

69 115 45 116 117 32 115 195 187 114 32 100 39 195 170

(14)

116 114 101 32 104 97 98 105 108 108 195 169 32 100 101 32 99 101 116 116 101 32 102 97 195 167 111 110 32 112 111 117 114 32 97 108 108 101 114 32 195 160 32 99 101 116 116

(15)

32 115 111 105 114 195 169 101 32 63

Fin du programme

Cette fois, nous voyons très clairement qu’il s’agit bien d’octets : le parcours nous en restitue toutes les valeurs numériques, en notation décimale. Du fait que les caractères accentués sont encodés sur deux octets en UTF-8, la fonctionlen()ne nous renvoie pas la même valeur pour la chaîne de caractères, et pour son équivalent encodé en UTF-8 dans une chaîne d’octets :

[35]: print(len(message2))

print(len(message2_octets))

67 73

L’écart observé est logique puisque la phrase demessage2contient 6 caractères accentués : cha- cun d’eux étant codés en UTF-8 occupe un octet de plus que leur homologue non accentué donc compte double aux yeux de la fonctionlen().

10.3.2 La méthode decode()

[36]: message3=b"Es-tu s\xc3\xbbr d'\xc3\xaatre habill\xc3\xa9 de cette fa\xc3\xa7on␣

,pour aller \xc3\xa0 cette soir\xc3\xa9e ?"

print(message3.decode('utf-8'))

Es-tu sûr d'être habillé de cette façon pour aller à cette soirée ? 10.3.3 Conclusion

Pour éviter ces problèmes d’encodage des caractères accentués dans un programme Python, il convient de faire commencer celui-ci par l’en-tête (header) suivant :

[37]: # -*- coding: utf-8 -*-

11 Transformer une chaîne de caractères en une liste

La méthode split() permet de transformer une chaîne de caractères comportant plusieurs sous- chaînes en une liste de sous chaînes. Le séparateur par défaut est l’espace séparant les sous- chaînes.

(16)

[38]: titre = "Welcome to the jungle"

liste_titre = titre.split() print(liste_titre)

['Welcome', 'to', 'the', 'jungle']

Il est également possible de préciser le séparateur entre les sous chaînes dans la méthodesplit() :

[39]: txt = "Hello, my name is Peter, I am 26 years old"

liste_txt = txt.split(", ") print(liste_txt)

['Hello', 'my name is Peter', 'I am 26 years old']

Nous verrons en détail les listes dans un prochain cours.

12 Activités pour vous entraîner

Activité 1 : Ecrire un programme Python qui afiche le caractère (et son code en base 10) ayant le plus petit code ASCII dans une chaîne de caractères non accentués.

Activité 2 : Ecrire un programme Python qui affiche le code ASCII en base 10 de chaque caractère constituant une chaîne de caractères non accentués.

Activité 3 :Ecrire un programme Python qui affiche automatiquement les lettres de l’alphabet en majuscule et en minuscule. Codes ASCII : A (65) Z(90)

Activité 4 : Ecrire un programme Python qui inverse tous les éléments d’une chaîne de carac- tères.

Références

Documents relatifs

Il faut donc faire défiler le message dans buffer, c'est à dire copier message dans buffer à partir d'une position donnée, afficher son contenu pendant un instant donné

L’ensemble des couples (X,Y) constitue une distribution à deux caractères, ou distribution à deux variables. Exemple : On considère la note en maths et en français de 12

[r]

[r]

- Ecrire une fonction récursive qui calcule le PGCD de deux entiers positifs. On suppose qu’on ne peut effectuer que

Une pile est représentée par une structure regroupant un entier, pour le sommet, et un tableau de MAX_PILE éléments (ici, des caractères). II.1- En utilisant la

Dans la liste des périodes possibles, on trouve avec une période telle que abcde les périodes bcdea, cdeab, deabc, eabcd ; d’où 10 périodes multiples de 2439, compatibles avec 41

Il est par contre possible de réaliser des conversions : on retiendra que la fonction str permet de convertir un objet en chaine de caractères et les fonctions float et int