11  Les chaînes de caractères

Les chaînes de caractères (str) sont omniprésentes en programmation : noms, messages, données lues depuis un fichier, réponses utilisateur… Ce chapitre est l’un des plus importants du niveau Basique car le TOSA évalue énormément les méthodes de chaînes.

11.1 Création d’une chaîne

Les chaînes se créent avec des guillemets simples '...', doubles "..." ou triples """...""" pour plusieurs lignes.

nom = "Alice"
ville = 'Paris'
texte_long = """Ceci est une chaîne
sur plusieurs
lignes."""

print(nom)
print(ville)
print(texte_long)
Alice
Paris
Ceci est une chaîne
sur plusieurs
lignes.

Guillemets dans une chaîne

Pour inclure le caractère du délimiteur, on alterne les types :

phrase1 = "Il a dit \"bonjour\""          # échappement avec \
phrase2 = 'Il a dit "bonjour"'            # alternance plus lisible
phrase3 = "L'ami de Bob"                   # apostrophe dans guillemets doubles

print(phrase1)
print(phrase2)
print(phrase3)
Il a dit "bonjour"
Il a dit "bonjour"
L'ami de Bob

Caractères spéciaux

Séquence Signification
\n Saut de ligne
\t Tabulation
\\ Backslash \
\" Guillemet double dans une chaîne "..."
\' Apostrophe dans une chaîne '...'
print("Ligne 1\nLigne 2")
print("Colonne1\tColonne2")
print("Chemin : C:\\Users\\Alice")
Ligne 1
Ligne 2
Colonne1    Colonne2
Chemin : C:\Users\Alice

11.2 Concaténation et répétition

On assemble des chaînes avec +, on répète avec * :

salutation = "Bonjour "
nom = "Alice"
message = salutation + nom + " !"
print(message)
Bonjour Alice !
ligne = "-" * 30
print(ligne)
print("Titre")
print(ligne)
------------------------------
Titre
------------------------------
⚠️ Piège TOSA : + ne fonctionne qu’entre chaînes

On ne peut pas concaténer directement une chaîne et un nombre :

age = 30
print("J'ai " + age + " ans")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[6], line 2
      1 age = 30
----> 2 print("J'ai " + age + " ans")

TypeError: can only concatenate str (not "int") to str

Il faut convertir le nombre avec str() :

age = 30
print("J'ai " + str(age) + " ans")
J'ai 30 ans

Ou mieux, utiliser print avec des virgules :

print("J'ai", age, "ans")
J'ai 30 ans

Ou encore mieux, une f-string (vu en Partie 2) :

print(f"J'ai {age} ans")
J'ai 30 ans

11.3 Indexation

Chaque caractère d’une chaîne a un indice, à partir de 0.

Chaîne  :  P  y  t  h  o  n
Indice+ :  0  1  2  3  4  5
Indice- : -6 -5 -4 -3 -2 -1

Les indices négatifs partent de la fin : -1 est le dernier caractère.

mot = "Python"
print(mot[0])       # 'P'
print(mot[3])       # 'h'
print(mot[-1])      # 'n' (dernier)
print(mot[-2])      # 'o' (avant-dernier)
P
h
n
o
⚠️ Piège TOSA : dépassement d’indice

Accéder à un indice hors limites lève une IndexError :

mot = "Python"
print(mot[10])
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[11], line 2
      1 mot = "Python"
----> 2 print(mot[10])

IndexError: string index out of range

11.4 Le slicing (découpage)

La syntaxe chaine[debut:fin:pas] extrait une sous-chaîne.

  • debut : indice de départ (inclus) — par défaut 0.
  • fin : indice d’arrivée (exclu) — par défaut fin de chaîne.
  • pas : pas entre les caractères — par défaut 1.
mot = "Python"
print(mot[0:3])       # 'Pyt' (caractères 0, 1, 2 — 3 est EXCLU)
print(mot[2:5])       # 'tho'
print(mot[:3])        # 'Pyt' (depuis le début)
print(mot[3:])        # 'hon' (jusqu'à la fin)
print(mot[:])         # 'Python' (copie complète)
Pyt
tho
Pyt
hon
Python

Le pas (step)

Le troisième paramètre permet de sauter des caractères.

alphabet = "abcdefghij"
print(alphabet[::2])    # un caractère sur deux : 'acegi'
print(alphabet[1::2])   # un sur deux, en commençant au 2ème : 'bdfhj'
print(alphabet[::-1])   # inverser ! 'jihgfedcba'
acegi
bdfhj
jihgfedcba
Astuce : inverser une chaîne

chaine[::-1] est l’idiome Python pour inverser une chaîne.

print("Python"[::-1])
nohtyP

Slicing tolérant

À la différence de l’indexation, le slicing ne lève pas d’erreur si les indices sont hors limites :

mot = "Python"
print(mot[0:100])     # pas d'erreur : renvoie 'Python'
print(mot[50:60])     # pas d'erreur : renvoie '' (chaîne vide)
Python

11.5 Les chaînes sont immuables

Une chaîne ne peut pas être modifiée après sa création. On dit qu’elle est immuable (immutable).

mot = "Python"
mot[0] = "J"        # ❌ Impossible !
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[16], line 2
      1 mot = "Python"
----> 2 mot[0] = "J"        # ❌ Impossible !

TypeError: 'str' object does not support item assignment

Pour « modifier » une chaîne, on en crée une nouvelle :

mot = "Python"
nouveau = "J" + mot[1:]
print(nouveau)
Jython

11.6 Longueur et appartenance

len() donne la longueur (nombre de caractères). in teste la présence d’une sous-chaîne.

mot = "anticonstitutionnellement"
print("Longueur :", len(mot))

print("on" in mot)           # True
print("zzz" in mot)          # False
print("on" not in mot)       # False
Longueur : 25
True
False
False

11.7 Les méthodes de chaînes (à connaître par cœur pour le TOSA)

Python offre une cinquantaine de méthodes sur les chaînes. Voici les plus importantes, toutes testées au TOSA.

Règle d’or : les méthodes renvoient une NOUVELLE chaîne

Les méthodes ne modifient jamais la chaîne originale (elle est immuable). Elles renvoient une nouvelle chaîne transformée.

mot = "python"
mot.upper()             # renvoie 'PYTHON' mais NE MODIFIE PAS mot
print(mot)              # toujours 'python'

mot = mot.upper()       # pour "modifier", il faut RÉAFFECTER
print(mot)              # maintenant 'PYTHON'
python
PYTHON

Casse (majuscules / minuscules)

Méthode Effet Exemple
upper() Tout en majuscules "abc".upper()"ABC"
lower() Tout en minuscules "ABC".lower()"abc"
title() Première lettre de chaque mot en majuscule "bonjour alice".title()"Bonjour Alice"
capitalize() Première lettre en majuscule, reste en minuscules "BONJOUR".capitalize()"Bonjour"
swapcase() Inverse casse "aBc".swapcase()"AbC"
texte = "bonjour TOSA"
print(texte.upper())
print(texte.lower())
print(texte.title())
print(texte.capitalize())
print(texte.swapcase())
BONJOUR TOSA
bonjour tosa
Bonjour Tosa
Bonjour tosa
BONJOUR tosa

Recherche

Méthode Effet
find(sub) Indice de la première occurrence ou -1 si non trouvée
index(sub) Idem, mais lève ValueError si non trouvée
count(sub) Nombre d’occurrences
startswith(sub) Commence par sub ?
endswith(sub) Finit par sub ?
phrase = "Python est un langage puissant. Python est populaire."
print("Position de 'Python' :", phrase.find("Python"))
print("Position de 'Java' :", phrase.find("Java"))      # -1
print("Occurrences de 'Python' :", phrase.count("Python"))
print("Commence par 'Python' :", phrase.startswith("Python"))
print("Finit par '!' :", phrase.endswith("!"))
Position de 'Python' : 0
Position de 'Java' : -1
Occurrences de 'Python' : 2
Commence par 'Python' : True
Finit par '!' : False
⚠️ Piège TOSA : find vs index
  • find() renvoie -1 si non trouvé — ne plante jamais.
  • index() lève une exception si non trouvé.

Choisissez find() quand vous ne savez pas si la sous-chaîne est présente.

"bonjour".index("z")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[22], line 1
----> 1 "bonjour".index("z")

ValueError: substring not found

Nettoyage

Méthode Effet
strip() Retire espaces et tabulations aux deux extrémités
lstrip() Idem, uniquement à gauche
rstrip() Idem, uniquement à droite
strip(chars) Retire les caractères listés dans chars
texte = "   Bonjour TOSA   \n"
print(repr(texte.strip()))
print(repr(texte.lstrip()))
print(repr(texte.rstrip()))

# Avec des caractères spécifiques
print("###titre###".strip("#"))     # 'titre'
'Bonjour TOSA'
'Bonjour TOSA   \n'
'   Bonjour TOSA'
titre

(repr() affiche la chaîne avec ses caractères spéciaux visibles.)

Remplacement et séparation

Méthode Effet
replace(old, new) Remplace toutes les occurrences
replace(old, new, n) Remplace les n premières occurrences
split(sep) Découpe en liste selon sep
split() sans arg Découpe selon tout espace blanc
sep.join(liste) Recolle une liste avec sep entre chaque
phrase = "Le chat de Paul aime le chat du voisin."
print(phrase.replace("chat", "chien"))
print(phrase.replace("chat", "chien", 1))   # une seule fois
Le chien de Paul aime le chien du voisin.
Le chien de Paul aime le chat du voisin.
phrase = "Python est un langage"
mots = phrase.split()
print(mots)
['Python', 'est', 'un', 'langage']
csv = "Alice,Bob,Charlie,Diana"
noms = csv.split(",")
print(noms)

# Recoller avec un autre séparateur
print(" | ".join(noms))
['Alice', 'Bob', 'Charlie', 'Diana']
Alice | Bob | Charlie | Diana

Tests sur le contenu

Ces méthodes renvoient un booléen selon la nature des caractères.

Méthode Vraie si la chaîne contient…
isdigit() uniquement des chiffres
isalpha() uniquement des lettres
isalnum() uniquement des lettres ou chiffres
isspace() uniquement des espaces blancs
isupper() toutes les lettres en majuscules
islower() toutes les lettres en minuscules
print("123".isdigit())          # True
print("12.5".isdigit())         # False (le point n'est pas un chiffre)
print("abc".isalpha())          # True
print("abc123".isalnum())       # True
print("   ".isspace())          # True
print("PYTHON".isupper())       # True
True
False
True
True
True
True

Enchaîner les méthodes

Puisque chaque méthode renvoie une chaîne, on peut les enchaîner directement :

texte = "   Bonjour TOSA   \n"
propre = texte.strip().lower().replace("tosa", "python")
print(propre)
bonjour python

C’est idiomatique en Python et très efficace.

11.8 Les entrées / sorties de base

input() — lire

input() attend une saisie de l’utilisateur et renvoie toujours une chaîne.

nom = input("Votre nom ? ")
age_txt = input("Votre âge ? ")
age = int(age_txt)               # conversion nécessaire pour calculer

print("Bonjour", nom, "vous aurez", age + 1, "ans l'an prochain.")
⚠️ Rappel TOSA incontournable

input() renvoie toujours une str, même si l’utilisateur tape un nombre. Pour les calculs, il faut convertir avec int() ou float().

11.9 Le mot-clé pass

pass est une instruction vide — elle ne fait rien. On l’utilise là où Python exige une instruction mais qu’on n’a encore rien à y mettre.

def ma_fonction():
    pass   # placeholder, à compléter plus tard

if condition:
    pass   # on ne fait rien dans ce cas
else:
    traiter()

Sans pass, on aurait une IndentationError : Python refuse un bloc vide.


🧩 Quiz 1.3 — Chaînes de caractères

Question 1

Que vaut "Python"[1:4] ?

  1. "Pyt"
  2. "yth"
  3. "ytho"
  4. "yh"

b) "yth" — indices 1, 2, 3 (l’indice 4 est exclu).

print("Python"[1:4])
yth

Question 2

Que vaut "Python"[-1] ?

  1. "P"
  2. "n"
  3. "o"
  4. Une erreur

b) "n" — l’indice -1 désigne le dernier caractère.

print("Python"[-1])
n

Question 3

Que renvoie "abc" * 3 ?

  1. "abcabcabc"
  2. "abc3"
  3. "a3b3c3"
  4. Une erreur

a) "abcabcabc" — l’opérateur * répète une chaîne.

print("abc" * 3)
abcabcabc

Question 4

Quel code renverse la chaîne "Python" pour donner "nohtyP" ?

  1. "Python".reverse()
  2. "Python"[::-1]
  3. reversed("Python")
  4. "Python".inverse()

b) "Python"[::-1] — le slicing avec pas négatif. reverse() n’existe pas sur les chaînes, reversed() renvoie un itérateur (pas une chaîne).

print("Python"[::-1])
nohtyP

Question 5

Que s’affiche-t-il ?

mot = "Python"
mot.upper()
print(mot)
  1. "Python"
  2. "PYTHON"
  3. "python"
  4. Une erreur

a) "Python" — les méthodes de chaîne ne modifient pas la chaîne originale (elle est immuable). upper() renvoie une nouvelle chaîne, mais elle est ici ignorée (non affectée).

mot = "Python"
mot.upper()
print(mot)
Python

Pour « modifier », il faut réaffecter :

mot = "Python"
mot = mot.upper()
print(mot)
PYTHON

Question 6

Que renvoie "a,b,c,d".split(",") ?

  1. "a b c d"
  2. ["a", "b", "c", "d"]
  3. ("a", "b", "c", "d")
  4. "abcd"

b) ["a", "b", "c", "d"]split() renvoie une liste de chaînes.

print("a,b,c,d".split(","))
print(type("a,b,c,d".split(",")))
['a', 'b', 'c', 'd']
<class 'list'>

Question 7

Que renvoie " Python ".strip() ?

  1. "Python"
  2. " Python "
  3. "python"
  4. Une erreur

a) "Python"strip() retire les espaces (et autres blancs) aux deux extrémités.

print(repr(" Python ".strip()))
'Python'

Question 8

Quelle affirmation est VRAIE à propos des chaînes Python ?

  1. Elles sont modifiables avec mot[0] = "X".
  2. Elles sont immuables (on ne peut pas modifier un caractère).
  3. Elles ne peuvent pas contenir d’accents.
  4. len() ne fonctionne pas dessus.

b) — les chaînes Python sont immuables. Toute « modification » produit en réalité une nouvelle chaîne.


✏️ Exercice 3.1 — Manipulations de base

Soit la chaîne phrase = " Bonjour le monde ! ".

Écrivez un programme qui :

  1. Affiche la longueur de la chaîne (espaces compris).
  2. Affiche la chaîne sans les espaces de début et fin.
  3. Affiche la chaîne entièrement en majuscules.
  4. Remplace “monde” par “TOSA”.
  5. Vérifie si “bonjour” (en minuscules) est dans la chaîne.
phrase = "  Bonjour le monde !  "

# 1. Longueur
...

# 2. Sans espaces aux extrémités
...

# 3. Majuscules
...

# 4. Remplacer "monde" par "TOSA"
...

# 5. Vérifier si "bonjour" est présent (en minuscules)
...
phrase = "  Bonjour le monde !  "

# 1. Longueur
print("Longueur :", len(phrase))

# 2. Sans espaces
print("Nettoyée :", repr(phrase.strip()))

# 3. Majuscules
print("Majuscules :", phrase.upper())

# 4. Remplacer
print("Remplacée :", phrase.replace("monde", "TOSA"))

# 5. "bonjour" présent (attention à la casse !)
print("'bonjour' présent :", "bonjour" in phrase.lower())
Longueur : 22
Nettoyée : 'Bonjour le monde !'
Majuscules :   BONJOUR LE MONDE !  
Remplacée :   Bonjour le TOSA !  
'bonjour' présent : True
  • On utilise .lower() dans la question 5 car la chaîne contient "Bonjour" (avec B majuscule), pas "bonjour".
  • repr() permet de visualiser les espaces dans la sortie (utile pour vérifier strip()).

✏️ Exercice 3.2 — Initiales

Demandez le prénom et le nom à l’utilisateur, et affichez ses initiales en majuscules séparées par un point.

Exemple : Alice DupontA.D.

prenom = input("Prénom : ")
nom = input("Nom : ")

# Extraire la première lettre de chaque, les mettre en majuscule, les joindre
initiales = ...

print("Initiales :", initiales)
prenom = "Alice"     # au lieu de input()
nom = "Dupont"

initiales = prenom[0].upper() + "." + nom[0].upper() + "."
print("Initiales :", initiales)
Initiales : A.D.

Pour gérer les espaces en trop et les casses variables :

prenom = "  alice  "
nom = "DUPONT"

# .strip() pour retirer les espaces éventuels
initiales = prenom.strip()[0].upper() + "." + nom.strip()[0].upper() + "."
print("Initiales :", initiales)
Initiales : A.D.
prenom = "Alice"
nom = "Dupont"
initiales = f"{prenom[0].upper()}.{nom[0].upper()}."
print(initiales)
A.D.

✏️ Exercice 3.3 — Palindrome

Un palindrome est un mot qui se lit de la même manière dans les deux sens (ex: radar, kayak, sos).

Écrivez un programme qui teste si une chaîne donnée est un palindrome (ignorez la casse).

mot = input("Entrez un mot : ")

# Comparer mot (en minuscules) à son inversion
...

if ...:
    print(mot, "est un palindrome")
else:
    print(mot, "n'est pas un palindrome")
def est_palindrome(mot):
    mot = mot.lower()
    return mot == mot[::-1]

# Tests
for m in ["radar", "Kayak", "sos", "Python", "Laval"]:
    if est_palindrome(m):
        print(m, "→ palindrome ✅")
    else:
        print(m, "→ pas palindrome ❌")
radar → palindrome ✅
Kayak → palindrome ✅
sos → palindrome ✅
Python → pas palindrome ❌
Laval → palindrome ✅

En retirant aussi les espaces et la ponctuation :

def est_palindrome_robuste(phrase):
    # Ne garder que les lettres, en minuscules
    propre = "".join(c for c in phrase.lower() if c.isalpha())
    return propre == propre[::-1]

phrases = [
    "Esope reste ici et se repose",
    "Un radar",
    "Bonjour",
]
for p in phrases:
    print(f"'{p}' → {est_palindrome_robuste(p)}")
'Esope reste ici et se repose' → True
'Un radar' → False
'Bonjour' → False

Note : la syntaxe "".join(...) et les compréhensions seront vues en Partie 3.


À retenir

Points clés du chapitre
  1. Les chaînes sont immuables : les méthodes renvoient une nouvelle chaîne.
  2. Indexation à partir de 0. Les indices négatifs partent de la fin.
  3. Slicing [debut:fin:pas] : debut inclus, fin exclu. [::-1] inverse.
  4. + concatène, * répète, in teste l’appartenance.
  5. Les méthodes-clé à connaître pour le TOSA : upper, lower, strip, replace, split, join, find, count, startswith, endswith.
  6. find renvoie -1 si absent ; index lève une exception.
  7. On peut enchaîner les méthodes : texte.strip().lower().replace(...).
  8. input() renvoie toujours une chaîne — convertissez-la pour calculer.

← Chapitre précédent : OpérateursChapitre suivant : Conditions →