python index string

Identification

Infoforall

22 - (Bilan) Strings


Nous allons voir aujourd'hui un plus en détails les strings.

Il s'agit de variables qui font référence à des caractères contenus dans la chaine de caractères. On peut donc lire le string un caractère à la fois.

Logiciel nécessaire pour l'activité : Thonny ou juste Python 3

Evaluation ✎ : -

Documents de cours : open document ou pdf

Exercices corrigés complémentaires de cours : exos

1 - Le cours sur les strings

1 - Déclaration d'un string avec des guillemets en Python (RAPPEL)

Les éléments délimitateurs sont les guillemets.

On peut utiliser les guillemets simples ou doubles mais Python utilise les simples lors des affichages de "contenu".

Exemple

>>> a = "5" >>> a*2 '55' >>> type(a) <class 'str'> >>> type(a*2) <class 'str'>
2 - Nombre d'éléments stockés avec len (RAPPEL)

On peut utiliser la fonction native len pour obtenir le nombre de caractères stockés dans le string.

Exemple

>>> a = "bonjour" >>> len(a) 7 >>> nbr = len(a) >>> nbr 7 >>> a = "bonjour !" >>> nbr = len(a) >>> nbr 9

On notera que l'espace est bien un caractère : il s'agit du caractère de code ASCII 32.

3 - Accès à l'un des éléments avec [indice] (RAPPEL)

Pour lire un caractère, on écrit le nom de la variable suivi de crochets et on y place l'indice de la case voulu.

Exemple

>>> a = "bonjour" >>> a[0] 'b' >>> b[1] 'o' >>> lettre = a[0] >>> lettre 'b' >>> lettre = a[1] >>> lettre 'o' >>> lettre = a[5] >>> lettre 'u'

La correspondance indice - caractère donne ceci sur l'exemple

indice 0 1 2 3 4 5 6
'bonjour' 'b' 'o' 'n' 'j' 'o' 'u' 'r'

On notera que l'indice du premier élément porte le numéro d'indice 0 et pas le numéro 1 !

4 - Lecture des éléments un à un par indice (méthode avec indice numérique, avec range) (RAPPEL)

On peut lire les caractères du string un par un en utilisant une boucle FOR couplée à la fonction len pour connaitre la valeur limite à donner à la variable de boucle.

Ainsi avec "bonjour", on a 7 lettres avec un indice 0-1-2-3-4-5-6.

0123456 s = "bonjour"

Il faudrait donc utiliser for i in range(7), ce qui permettra à la variable de boucle i de prendre successivement les valeurs 0, puis 1 lors du tour de boucle suivant, puis 2, puis 3, puis 4, puis 5, puis 6, et enfin 7.

Exemple

1 2 3 4
s = "bonjour" for i in range(len(s)): # Pour chaque indice possible dans s print(s[i])

Ce programme est équivalent à ceci :

1 2 3 4 5 6 7 8 9
s = "bonjour" print(s[0]) print(s[1]) print(s[2]) print(s[3]) print(s[4]) print(s[5]) print(s[6])

Ils affichent l'un et l'autre ceci dans la console :

b o n j o u r

Point important :

  • La variable de boucle i contient l'indice d'une case, pas son contenu.
  • On lit le contenu de la case i à l'aide de s[i]
5 - Lecture des éléments un à un (méthode nominative, sans range) (NOUVEAU)

Cette gestion nominative d'itérer les éléments que nous allons voir ici n'existe pas dans tous les langages.

Python ou Javascript l'utilisent.

Cela permet parfois d'avoir un code plus lisible, au détriment de la connaissance de l'indice i de l'élément en train d'être traité.

1 2 3 4 5 6 7 8 9
phrase1 = "bonjour, je suis la seconde façon de faire !" nbr_e = 0 for caractere in phrase1: print(caractere) if caractere == 'e': nbr_e = nbr_e + 1 print(f"Il y a eu {nbr_e} 'e' dans cette phrase.")

Point important : ici, pas range, juste le nom du string phrase1 derrière le in : la variable de boucle contient directement le caractère.

Ici, on lit le contenu à l'aide de caractere : la variable de boucle caractere va prendre successivement les valeurs 'b', puis 'o' lors du tour de boucle suivant, puis 'n'...

Ce programme affiche tout simplement les caractères un à un sans avoir à passer par un indice dans le code :

b o n j o u r , j e s u i s l a s e c o n d e f a ç o n d e f a i r e ! Il y a eu 5 'e' dans cette phrase.

On peut utiliser une variable de boucle plus courte (c plutôt que caractere) et supprimer le print qui affiche les caractères un par un. Voici le programme plus concis :

1 2 3 4 5 6 7 8
phrase1 = "bonjour, je suis la seconde façon de faire !" nbr_e = 0 for c in phrase1: if c == 'e': nbr_e = nbr_e + 1 print(f"Il y a eu {nbr_e} 'e' dans cette phrase.")

Autre point important : ne confondez pas

  • for c in s qui crée une boucle avec une variable de boucle qui contiendra à chaque tour de boucle l'un des caractères du string.
  • if c in s qui renvoie un booléen et teste si le caractère c se trouve dans le string s.
6 - "numérique" contre "nominatif"  Lequel choisir ?

Le choix de l'un ou l'autre dépend des situations.

Situation 1

Si vous avez besoin de connaître l'indice du caractère que vous examinez, il faut utiliser un for "numérique" :

Exemple : vous ne voulez afficher qu'un caractère sur 2.

1 2 3 4 5
s = 'bonjour' longueur = len(s) for i in range(0, longueur, 2): print(s[i])

Ce programme va afficher ceci dans la console :

b n o r

Situation 2

Si vous n'avez pas besoin de connaître l'indice de l'élément que vous examinez, vous pouvez utiliser la version que vous voulez.

  • for i in range(len(s)) avec un accès au caractère avec s[i]
  • for c in s avec un accès au caractère avec c
7 - Immuabilité des strings EN PYTHON

En Python, les strings sont immuables (ou non mutables en franglais) : cela veut dire qu'on ne peut pas modifier les caractères d'un string après sa création.

>>> a = "bonjour" >>> a[0] = "d" TypeError: 'str' object does not support item assignment

D'autres langages se comportent comme Python : Java, C#, JavaScript...

Comment faire alors pour modifier un string ?

On ne peut pas !

Par contre, on peut tricher et créer un nouveau string à partir de l'ancien puis l'affecter à une variable qui porte le même nom que l'ancienne !

VERSION avec indice (boucle "numérique")

1 2 3 4 5 6 7 8 9 10 11 12
texte = "bonjour" tempo = "" for i in range(len(texte)): c = texte[i] if c == 'o': tempo = tempo + 'X' else: tempo = tempo + c texte = tempo print(texte)

Voici le contenu modifié à chaque tour de boucle (lignes 4 à 9) de la variable tempo.

i contient 0, d'où : b i contient 1, d'où : bX i contient 2, d'où : bXn i contient 3, d'où : bXnj i contient 4, d'où : bXnjX i contient 5, d'où : bXnjXu i contient 6, d'où : bXnjXur

Attention : dans le code ci-dessous, il y a deux variables texte qui ne référence pas la même zone mémoire, avant et après "modification".

  • Ligne 1 : avant modification, texte pointe vers l'identifiant-mémoire 12
  • Ligne 11 : après modification, texte pointe vers l'identifiant-mémoire 18
String non mutable
Visualisation des modifications

VERSION sans indice (boucle "nominative")

1 2 3 4 5 6 7 8 9 10 11
texte = "bonjour" tempo = "" for c in texte: if c == 'o': tempo = tempo + 'X' else: tempo = tempo + c texte = tempo print(texte)

Voici le contenu modifié à chaque tour de boucle (lignes 4 à 8) de la variable tempo.

c contient 'b', d'où : b c contient 'o', d'où : bX c contient 'n', d'où : bXn c contient 'j', d'où : bXnj c contient 'o', d'où : bXnjX c contient 'u', d'où : bXnjXu c contient 'r', d'où : bXnjXur

Dans d'autres langages (Ocaml, PHP, Ruby, C++...), le string est muable : on peut changer directement la valeur d'un caractère.

2 - Exercices

1 - Déclaration d'un string avec des guillemets en Python (RAPPEL)

Les éléments délimitateurs sont les guillemets.

On peut utiliser les guillemets simples ou doubles mais Python utilise les simples lors des affichages de "contenu".

Exemple

>>> a = "5" >>> a*2 '55' >>> type(a) <class 'str'> >>> type(a*2) <class 'str'>
2 - Nombre d'éléments stockés avec len (RAPPEL)

On peut utiliser la fonction native len pour obtenir le nombre de caractères stockés dans le string.

Exemple

>>> a = "bonjour" >>> len(a) 7 >>> nbr = len(a) >>> nbr 7 >>> a = "bonjour !" >>> nbr = len(a) >>> nbr 9

On notera que l'espace est bien un caractère : il s'agit du caractère de code ASCII 32.

01° Réaliser un programme qui stocke dans deux variables nb1 et nb2 le nombre de caractères présents dans les deux strings fournis ci-dessous.

Phrase 1

On notera que l'indice du premier élément ne porte pas le numéro 1 mais bien le numéro 0 !

Phrase 2

On notera également qu'on peut avoir accès à l'élément 5 sans avoir lu au préalable le 2,3 et 4. Ce n'est pas le cas pour toutes les structures de données.

...CORRECTION...

Programme qui mémorise

1 2 3 4 5
phrase1 = "On notera que l'indice du premier élément ne porte pas le numéro 1 mais bien le numéro 0 !" phrase2 = "On notera également qu'on peut avoir accès à l'élément 5 sans avoir lu au préalable le 2,3 et 4. Ce n'est pas le cas pour toutes les structures de données." nb1 = len(phrase1) nb2 = len(phrase2)
3 - Accès à l'un des éléments avec [indice] (RAPEL)

Pour lire un caractère, on écrit le nom de la variable suivi de crochets et on y place l'indice de la case voulu.

Exemple

>>> a = "bonjour" >>> a[0] 'b' >>> b[1] 'o' >>> lettre = a[0] >>> lettre 'b' >>> lettre = a[1] >>> lettre 'o' >>> lettre = a[5] >>> lettre 'u'

La correspondance indice - caractère donne ceci sur l'exemple

indice 0 1 2 3 4 5 6
'bonjour' 'b' 'o' 'n' 'j' 'o' 'u' 'r'

On notera que l'indice du premier élément porte le numéro d'indice 0 et pas le numéro 1 !

02° Trouver le 27e caractére de chacune des phrases suivantes (attention, il s'agit donc du caractère d'indice... 26) :

Phrase 1

On notera que l'indice du premier élément ne porte pas le numéro 1 mais bien le numéro 0 !

Phrase 2

On notera également qu'on peut avoir accès à l'élément 5 sans avoir lu au préalable le 2,3 et 4. Ce n'est pas le cas pour toutes les structures de données.

Vous réaliserez un programme qui les affiche dans la console uniquement. Pas de mémorisation.

...CORRECTION...

1 2 3 4 5
phrase1 = "On notera que l'indice du premier élément ne porte pas le numéro 1 mais bien le numéro 0 !" phrase2 = "On notera également qu'on peut avoir accès à l'élément 5 sans avoir lu au préalable le 2,3 et 4. Ce n'est pas le cas pour toutes les structures de données." print(phrase1[26]) print(phrase2[26])
4 - Lecture des éléments un à un par indice (méthode avec indice numérique, avec range) (RAPPEL)

On peut lire les caractères du string un par un en utilisant une boucle FOR couplée à la fonction len pour connaitre la valeur limite à donner à la variable de boucle.

Ainsi avec "bonjour", on a 7 lettres avec un indice 0-1-2-3-4-5-6.

0123456 s = "bonjour"

Il faudrait donc utiliser for i in range(7), ce qui permettra à la variable de boucle i de prendre successivement les valeurs 0, puis 1 lors du tour de boucle suivant, puis 2, puis 3, puis 4, puis 5, puis 6, et enfin 7.

Exemple

1 2 3 4
s = "bonjour" for i in range(len(s)): # Pour chaque indice possible dans s print(s[i])

Ce programme est équivalent à ceci :

1 2 3 4 5 6 7 8 9
s = "bonjour" print(s[0]) print(s[1]) print(s[2]) print(s[3]) print(s[4]) print(s[5]) print(s[6])

Ils affichent l'un et l'autre ceci dans la console :

b o n j o u r

Point important :

  • La variable de boucle i contient l'indice d'une case, pas son contenu.
  • On lit le contenu de la case i à l'aide de s[i]

03° Réaliser d'abord un court programme qui affiche caractère par caractère l'une de deux phrases précédentes.

Ensuite, s'arranger pour que le programme compte les "e" en utilisant un compteur nbr_e. Il faudra l'initialiser avant de rentrer dans la boucle : un humain crée et place automatiquement ce compteur à 0 lorsqu'on lui demande de compter. L'ordinateur non.

On rappelle que pour incrémenter, il faut utiliser nbr_e = nbr_e + 1. Il faudra bien entendu utiliser une instruction conditionnelle if pour tester si le caractère est un e ou pas.

Phrase 1

On notera que l'indice du premier élément ne porte pas le numéro 1 mais bien le numéro 0 !

Phrase 2

On notera également qu'on peut avoir accès à l'élément 5 sans avoir lu au préalable le 2,3 et 4. Ce n'est pas le cas pour toutes les structures de données.

Vous devriez découvrir 11 et 16 'e' dans les phrases 1 et 2.

...CORRECTION...

1 2 3 4 5 6 7 8 9 10
phrase1 = "On notera que l'indice du premier élément ne porte pas le numéro 1 mais bien le numéro 0 !" nbr_e = 0 for i in range( len(phrase1) ): caractere = phrase1[i] print(caractere) if caractere == 'e': nbr_e = nbr_e + 1 print(f"Il y a eu {nbr_e} 'e' dans cette phrase.")
Finir le print par autre chose qu'un passage à la ligne

Si on désire voir les caractères s'afficher en les séparant par un tiret, on peut utiliser ceci :

1 2 3 4
s = 'bonjour' for i in range( len(s) ): print(s[i], end="-")

On obtient alors ceci

b-o-n-j-o-u-r-
5 - Lecture des éléments un à un (méthode nominative, sans range) (NOUVEAU)

Cette gestion nominative d'itérer les éléments que nous allons voir ici n'existe pas dans tous les langages.

Python ou Javascript l'utilisent.

Cela permet parfois d'avoir un code plus lisible, au détriment de la connaissance de l'indice i de l'élément en train d'être traité.

1 2 3 4 5 6 7 8 9
phrase1 = "bonjour, je suis la seconde façon de faire !" nbr_e = 0 for caractere in phrase1: print(caractere) if caractere == 'e': nbr_e = nbr_e + 1 print(f"Il y a eu {nbr_e} 'e' dans cette phrase.")

Point important : ici, pas range, juste le nom du string phrase1 derrière le in : la variable de boucle contient directement le caractère.

Ici, on lit le contenu à l'aide de caractere : la variable de boucle caractere va prendre successivement les valeurs 'b', puis 'o' lors du tour de boucle suivant, puis 'n'...

Ce programme affiche tout simplement les caractères un à un sans avoir à passer par un indice dans le code :

b o n j o u r , j e s u i s l a s e c o n d e f a ç o n d e f a i r e ! Il y a eu 5 'e' dans cette phrase.

On peut utiliser une variable de boucle plus courte (c plutôt que caractere) et supprimer le print qui affiche les caractères un par un. Voici le programme plus concis :

1 2 3 4 5 6 7 8
phrase1 = "bonjour, je suis la seconde façon de faire !" nbr_e = 0 for c in phrase1: if c == 'e': nbr_e = nbr_e + 1 print(f"Il y a eu {nbr_e} 'e' dans cette phrase.")

Autre point important : ne confondez pas

  • for c in s qui crée une boucle avec une variable de boucle qui contiendra à chaque tour de boucle l'un des caractères du string.
  • if c in s qui renvoie un booléen et teste si le caractère c se trouve dans le string s.

04° En utilisant la méthode du for "nominatif" (for c in s), réaliser un programme où on déclare une chaine de caractères (contenant ce que vous voulez) et qui compte le nombre de 'e' qu'elle contient. On stockera le résultat dans une variable nommée nbr_e.

Réaliser alors un programme qui compte (et stocke) les e, les a, les o et les i. Il affichera ensuite les résultats lettre par lettre à l'aide d'un fString.

...CORRECTION...

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
texte = "Ceci est la phrase que devra analyser votre programme" nbr_a = 0 nbr_e = 0 nbr_i = 0 nbr_o = 0 for c in texte: if c == 'e': nbr_e = nbr_e + 1 elif c == 'a': nbr_a = nbr_a + 1 elif c == 'i': nbr_i = nbr_i + 1 elif c == 'o': nbr_o = nbr_o + 1 print(f"Il y a eu {nbr_e} 'e', {nbr_a} 'a', {nbr_i} 'i' et {nbr_o} 'o' dans cette phrase.")
6 - "numérique" contre "nominatif" 

Le choix de l'un ou l'autre dépend des situations.

Situation 1

Si vous avez besoin de connaître l'indice du caractère que vous examinez, il faut utiliser un for "numérique" :

Exemple : vous ne voulez afficher qu'un caractère sur 2.

1 2 3 4 5
s = 'bonjour' longueur = len(s) for i in range(0, longueur, 2): print(s[i])

Ce programme va afficher ceci dans la console :

b n o r

Situation 2

Si vous n'avez pas besoin de connaître l'indice de l'élément que vous examinez, vous pouvez utiliser la version que vous voulez.

  • for i in range(len(s)) avec un accès au caractère avec s[i]
  • for c in s avec un accès au caractère avec c
7 - Immuabilité des strings EN PYTHON

En Python, les strings sont immuables (ou non mutables en franglais) : cela veut dire qu'on ne peut pas modifier les caractères d'un string après sa création.

>>> a = "bonjour" >>> a[0] = "d" TypeError: 'str' object does not support item assignment

D'autres langages se comportent comme Python : Java, C#, JavaScript...

Comment faire alors pour modifier un string ?

On ne peut pas !

Par contre, on peut tricher et créer un nouveau string à partir de l'ancien puis l'affecter à une variable qui porte le même nom que l'ancienne !

VERSION avec indice (boucle "numérique")

1 2 3 4 5 6 7 8 9 10 11 12
texte = "bonjour" tempo = "" for i in range(len(texte)): c = texte[i] if c == 'o': tempo = tempo + 'X' else: tempo = tempo + c texte = tempo print(texte)

Voici le contenu modifié à chaque tour de boucle (lignes 4 à 9) de la variable tempo.

i contient 0, d'où : b i contient 1, d'où : bX i contient 2, d'où : bXn i contient 3, d'où : bXnj i contient 4, d'où : bXnjX i contient 5, d'où : bXnjXu i contient 6, d'où : bXnjXur

Attention : dans le code ci-dessous, il y a deux variables texte qui ne référence pas la même zone mémoire, avant et après "modification".

  • Ligne 1 : avant modification, texte pointe vers l'identifiant-mémoire 12
  • Ligne 11 : après modification, texte pointe vers l'identifiant-mémoire 18
String non mutable
Visualisation des modifications

VERSION sans indice (boucle "nominative")

1 2 3 4 5 6 7 8 9 10 11
texte = "bonjour" tempo = "" for c in texte: if c == 'o': tempo = tempo + 'X' else: tempo = tempo + c texte = tempo print(texte)

Voici le contenu modifié à chaque tour de boucle (lignes 4 à 8) de la variable tempo.

c contient 'b', d'où : b c contient 'o', d'où : bX c contient 'n', d'où : bXn c contient 'j', d'où : bXnj c contient 'o', d'où : bXnjX c contient 'u', d'où : bXnjXu c contient 'r', d'où : bXnjXur

05° Créer une fonction sans_accent() qui possède un paramètre contenant un string. Elle doit renvoyer une copie de ce string en modifiant les 'é', 'ê' et 'è' en un simple 'e'.

Voici son prototype :

1
def sans_accent(texte:str) -> str

Voici le code à modifier :

1 2 3
def sans_accent(texte:str) -> str: """Renvoie une copie de texte mais en remplacant les caractères accentués par une version non accentuée""" return texte

Comme on ne s'intéresse pas à la place du caractère dans le string, vous pouvez utiliser la boucle for qui vous convient le mieux.

...CORRECTION...

1 2 3 4 5 6 7 8 9
def sans_accent(texte:str) -> str: """Renvoie une copie de texte mais en remplacant les caractères accentués par une version non accentuée""" tempo = "" for c in texte: if c == 'é' or c == 'è' or c == 'ê': tempo = tempo + 'e' else: tempo = tempo + c return tempo

06° Modifier et compléter la fonction etoile_mystere() qui renvoie un string de même taille que celui reçu en paramètre. Que doit faire la fonction ?

Elle doit créer un nouveau string où

  • le caractère d'indice i est inchangé.
  • si le caractère est un point ('.'), une virgule (','), ou un espace (' '), il est inchangé.
  • sinon, tous les autres caractères devront être remplacés par des étoiles ('*').
2 >>> etoile_mystere('Bonjour à toi .', 2) '**n**** * *** .'

Le 'n' reste 'n' car c'est le caractère d'indice 2.

Voici son prototype :

1
def etoile_mystere(texte:str, numero:int) -> str

Le principe de la fonction est donc de reconstruire un nouveau string en rajoutant un par un le nouveau caractère. Il faut utiliser un FOR "numérique" puisqu'on a besoin de connaître l'indice du caractère.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
def etoile_mystere(texte, numero): """Renvoie un string composé d'étoiles. Seuls le caractère d'indice fourni, le point, la virgule et les espaces sont inchangé :: param texte(str) :: le string qui sert de base de travail :: param numero(int) :: le numéro d'indice du caractère qu'on ne veut pas modifier :: return (str) :: le string composé surtout d'étoiles >>> etoile_mystere('bonjour',1) '*o*****' >>> etoile_mystere('Bonjour à tous !', 2) '**n**** * **** *' """ tempo = "" for i in range(len(texte)): pass return tempo

...CORRECTION...

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
def etoile_mystere(texte, numero): """Renvoie un string composé d'étoiles. Seuls le caractère d'indice fourni, le point, la virgule et les espaces sont inchangé :: param texte(str) :: le string qui sert de base de travail :: param numero(int) :: le numéro d'indice du caractère qu'on ne veut pas modifier ::return (str) :: le string composé surtout d'étoiles >>> etoile_mystere('bonjour',1) '*o*****' >>> etoile_mystere('Bonjour à tous !', 2) '**n**** * **** *' """ tempo = "" for i in range(len(texte)): if indice == numero: # Gestion du cas numéro d'indice voulu tempo = tempo + texte[i] elif texte[i] == '.' or texte[i] == ',' or texte[i] == ' ': # Gestion des caractères spéciaux tempo = tempo + texte[i] else: # Tous les autres cas tempo = tempo + '*' return tempo

3 - FAQ et compléments de cours à voir en classe entière

Il ne s'agit pas d'une vraie section FAQ pour une fois. C'est plutôt une annexe, avec quelques nouvelles connaissances à comprendre, mais pas à connaître. La plupart des tâches présentées peuvent être réalisées avec de simple boucle, mais cela crée un ensemble d'instructions bien plus longues que celles présentées ici. Rien d'exigible donc mais du bien pratique en Python.

1 – Tester la présence d’un caractère dans un string ?

1 2 3 4
s = "bonjour !" # s pour string test = 'o' in s or 'O' in s if test: print("Détection d’un o/O")

2 – Détecter qu’un caractère est une voyelle ?

1 2 3 4 5
voyelles = "AaEeYyUuIiOo" c = 'o' est_voyelle = c in voyelles if est_voyelle: print("c est une voyelle")

3 – Fonction-prédicat de détection d’une voyelle dans un string ?

Propre : boucle non bornée donc while.

1 2 3 4 5 6 7 8 9 10 11 12 13 14
def contient_une_voyelle_v1(s): """True si s contient une voyelle""" voyelles = "AaEeYyUuIiOo" detection = False imax = len(s) - 1 i = 0 while i <= imax and not detection: if s[i] in voyelles: detection = True i = i + 1 return detection

Plus court : boucle non bornée avec for+return.

1 2 3 4 5 6 7 8 9 10
def contient_une_voyelle_v2(s): """True si s contient une voyelle""" voyelles = "AaEeYyUuIiOo" for i in range(len(voyelles)): if s[i] in voyelles: return True return False

4 – Récupérer uniquement un bout de string ?

Solution avec des concaténations

1 2 3 4
0123456 s = "Bonjour" a = "" for i in range(2, 5): a = a + s[i]

a contient alors "njo".

Solution hors programme (SLICING) mais pratique.

1 2
s = "Bonjour" a = s[2:5]

a contient alors "njo".

5 – Nous avions vu la méthode split non  ?

La méthode des strings split() permet de créer un tableau où chaque case est un bout du string. Il faut lui fournir le caractère séparateur qui servira à la division.

>>> s = "Bonjour à tous !" >>> mots = s.split(' ') >>> mots ['Bonjour', 'à', 'tous', '!'] >>> mots[0] 'Bonjour'

On voit qu’avec s.split(' ') le caractère de séparation est l’espace.

6 – Dans le sens tableau vers string, c'est possible ?

On peut créer un string à partir d’un tableau dont les éléments sont des strings.

On utilise la méthode des tableaux join().

>>> mots = ['Bonjour', 'à', 'tous', '!'] >>> s = " ".join(mots) >>> s 'Bonjour à tous !' >>> s = "*".join(mots) >>> s 'Bonjour*à*tous*!' >>> s = "".join(mots) >>> s 'Bonjouràtous!' >>> s = "\n".join(mots) >>> s 'Bonjour\nà\ntous\n!' >>> print(s) Bonjour à tous !

Voici quelques exemples détaillés pour mieux comprendre le join().

On considère que le tableau t contient ['b', 'X', 'n', 'j', 'X', 'u', 'r'].

Utiliser "".join(t) revient à réaliser cette concaténation à la fin :

'b' + "" + 'X' + "" + 'n' + "" + 'j' + "" + 'X' + "" + 'u' + "" + 'r' + ""

Le résultat est donc "bXnjXur"

Utiliser "-".join(t) revient à réaliser cette concaténation à la fin :

'b' + "-" + 'X' + "-" + 'n' + "-" + 'j' + "-" + 'X' + "-" + 'u' + "-" + 'r' + "-"

Le résultat est donc "b-X-n-j-X-u-r-"

Utiliser "**".join(t) revient à réaliser cette concaténation à la fin :

'b' + "**" + 'X' + "**" + 'n' + "**" + 'j' + "**" + 'X' + "**" + 'u' + "**" + 'r' + "**"

Le résultat est donc "b**X**n**j**X**u**r**"

7 - Une meilleure façon de "modifier" un string ?

En réalité, créer un string par des concaténations successives est assez long car on crée plusieurs fois de suite un string qu'on écrase à chaque fois, jusqu'à obtenir le bon.

Comment faire autrement alors ?

Voici la bonne méthode.

Etape 1 - string en tableau : on créant un tableau à partir du string en utilisant la fonction native list().

1 2
s = "bonjour" t = list(s)

A partir de ce moment, la variable t est un tableau contenant un caractère du string initial par case.

>>> t ['b', 'o', 'n', 'j', 'o', 'u', 'r']

Pourquoi est-ce mieux ?

Réponse : car un tableau Python est mutable. Nous allons pouvoir modifier directement les cases, sans avoir à recréer un tableau.

Etape 2 - modification du tableau : on réalise toujours la boucle for case par case, mais il suffit cette fois de modifier uniquement les cases qui changent. Avant, on devait concatener, que la case change, ou pas.

1 2 3 4 5 6
s = "bonjour" t = list(s) for i in range(len(t)): if t[i] == 'o': t[i] = 'X'

Si on demande à voir t à partir de ce moment :

>>> t ['b', 'X', 'n', 'j', 'X', 'u', 'r']

Etape 3 - tableau en string : on crée un string en concaténant chaque case du tableau sans les séparer par quoi que ce soit ("") avec la méthode des strings join().

1 2 3 4 5 6 7 8
s = "bonjour" t = list(s) for i in range(len(t)): if t[i] == 'o': t[i] = 'X' s = "".join(t)

Si on demande à visualiser le nouveau contenu référencé par la variable  :

>>> s 'bXnjXur'

Et voilà.

Vous connaissez maintenant deux façons de modifier un string en Python :

  1. En créant succesivement plusieurs strings et en écrasant le string initial :
  2. 1 2 3 4 5 6 7 8 9 10 11
    texte = "bonjour" tempo = "" for i in range(len(texte)): c = texte[i] if c == 'o': tempo = tempo + 'X' else: tempo = tempo + c texte = tempo
  3. En créant un tableau, en le modifiant et en créant un string à partir du tableau :
  4. 1 2 3 4 5 6 7 8
    s = "bonjour" t = list(s) for i in range(len(t)): if t[i] == 'o': t[i] = 'X' s = "".join(t)

Des informations supplémentaires dans la partie FICHES

La prochaine fois, nous allons voir d'autres types de structures de données dans lesquelles placer d'autres choses que des caractères.

Activité publiée le 22 11 2020
Dernière modification : 07 09 2024
Auteur : ows. h.