En Python, les chaînes (str) sont des objets immuables, c'est-à-dire qu'il est impossible de modifier leur contenu après leur création. Toute opération modifiant une chaîne (comme la concaténation ou le remplacement de caractères) crée un nouvel objet chaîne. Cela garantit la sécurité et la prévisibilité du code, car vous n'avez pas à vous soucier de ce que quelqu'un pourrait modifier la chaîne de manière implicite ailleurs dans le code.
s = 'Hello' s2 = s.replace('H', 'J') # s reste 'Hello', et s2 sera 'Jello'
Contrairement aux chaînes, les listes en Python sont des objets mutables. Leur contenu peut être modifié sur place par indexation ou par des méthodes, ce qui peut parfois entraîner des effets indésirables si la même liste est utilisée à plusieurs endroits.
Du point de vue des performances : si vous devez souvent modifier de grandes chaînes (par exemple, dans une boucle), l'immuabilité peut entraîner une allocation de mémoire excessive et un ralentissement de l'exécution du code. Dans de tels cas, il est recommandé d'utiliser une liste pour accumuler les parties de la chaîne, puis de les assembler avec ''.join().
Exemple :
# Mauvais (lent pour de grandes quantités de données) : s = '' for word in words: s += word # À chaque étape, une nouvelle chaîne est créée # Bon : parts = [] for word in words: parts.append(word) s = ''.join(parts)
Question : Pourquoi le code "s += 'abc'" est-il plus rapide que "s = s + 'abc'" pour les chaînes ?
Réponse : Ce type de question est posé pour vérifier si la personne comprend que les deux opérations sont en fait équivalentes pour les chaînes (s += 'abc' crée un nouvel objet, tout comme s = s + 'abc') - c'est ainsi que le comportement des types est en Python. Pour les listes, le comportement est différent, car list += [...] mutifie l'objet, tandis que list = list + [...] crée un nouveau. Pour les chaînes, c'est toujours une nouvelle chaîne.
s = 'hi' s += 'abc' # Nouvel objet, la chaîne d'origine ne change pas def compare(s): a = s a += 'abc' # id(a) != id(s) <-- objets différents en mémoire
Histoire
Dans un projet nécessitant le traitement de grands journaux (parsing de chaînes de plusieurs centaines de mégaoctets), un développeur a utilisé la concaténation naïve de chaînes dans une boucle. Le résultat - une énorme baisse de performance et une augmentation rapide de la consommation mémoire. Après optimisation avec une liste et join(), le temps d'exécution a été réduit par 20.
Histoire
Dans un projet, en essayant de "corriger" un caractère dans une chaîne par index, le programmeur s'attendait à voir la chaîne d'origine changer. Une erreur est survenue : TypeError: 'str' object does not support item assignment. Après plusieurs heures, le débogueur a dû créer une nouvelle chaîne à l'aide de tranches et remplacer le caractère souhaité.
Histoire
Lors du passage de chaînes à une fonction pour "compléter" celles-ci (par exemple, ajouter un suffixe à chaque élément d'une liste), l'un des développeurs s'attendait à ce que la chaîne change "sur place". Le résultat - la fonction retournait None (en raison de l'absence de return), et toutes les chaînes restaient originales.