Combiner et concaténer des chaînes de caractères

Dans cet article, vous allez apprendre comment combiner plusieurs petites chaînes de caractères en une plus grande chaîne.

Si les chaines que vous souhaitez combiner se trouvent dans un objet de nature séquence ou itérable – comme une liste par exemple, la façon la plus rapide de les combiner est d’utiliser la méthode join(). Par exemple:

>>> parties = ['La', 'vie', 'est', '.difficile.']
>>> ' '.join(parties)
'La vie est difficile.'
>>> ','.join(parties)
'La,vie,est,difficile'
>>> ''.join(parties)
'Lavieestdifficile'
>>>

 

A première vue, cette syntaxe peut sembler vraiment étrange, mais l’opération join() est spécifiée comme une méthode sur les chaines de caractères.

C’est en partie parce que les objets que vous voulez joindre peuvent provenir d’un nombre quelconque de séquences de données différentes (par exemple, listes, tuples, dicts, fichiers, ensembles ou générateurs), et il serait redondant d’avoir join() implémenté comme une méthode sur tous ces objets séparément.

Il vous suffit donc de spécifier la chaîne de séparation que vous voulez et d’utiliser la méthode join() pour coller les fragments de texte ensemble.

Si vous ne combinez que quelques chaînes de caractères, l’utilisation du signe de concaténation “+” convient généralement assez bien:

>>> a = 'La vie'
>>> b = 'est belle.'
>>> a + ' ' + b
'La vie est belle.'
>>>

 

L’opérateur + fonctionne également très bien comme un substitut aux opérations de formatage de chaines plus compliquées. Par exemple:

>>> print('{} {}'.format(a,b))
La vie est belle.

>>> print(a + ' ' + b)
La vie est belle.
>>>

 

Si vous essayez de combiner des chaînes de caractères littéraux ensemble dans le code source, vous pouvez simplement les placer les unes à côté des autres sans opérateur +. Par exemple:

>>> a = 'Hello' 'World'
>>> a
'HelloWorld'
>>>

 

L’assemblage de chaînes de caractères peut ne pas sembler assez avancé pour justifier une recette complète, mais c’est souvent un domaine où les programmeurs font des choix de programmation qui ont un impact sévère sur la performance de leur code.

La chose la plus importante à savoir est que l’utilisation de l’opérateur + pour joindre beaucoup de chaînes de caractères ensemble est tout à fait inefficace en raison des copies de mémoire. En particulier, vous ne devez jamais écrire du code qui relie des chaînes de caractères ensemble comme ceci:

s = ''
for p in parts:
   s += p

 

Cela fonctionne un peu plus lentement qu’avec la méthode join(), principalement parce que chaque opération += crée un nouvel objet chaîne de caractères. Il vaut mieux se contenter de rassembler toutes les pièces d’abord et de les assembler à la fin.

Une astuce connexe (et assez nette) est la conversion des données en chaînes de caractères et la concaténation en même temps en utilisant une expression de générateur. Par exemple:

>>> donnee = ['Fone', 50, 91.1]
>>> ','.join(str(d) for d in donnee)
'Fone,50,91.1'
>>>

 

Parfois, les programmeurs se laissent emporter par la concaténation alors que ce n’est pas vraiment techniquement nécessaire. Par exemple, lors de l’affichage du texte avec la fonction print():

print(a + ':' + b + ':' + c) # Moche
print(':'.join([a, b, c])) # Encore moche

print(a, b, c, sep=':') # Mieux

 

Le fait de combiner les opérations d’E/S et la concaténation de chaînes de caractères peut nécessiter une étude dans votre application. Par exemple, considérons les deux fragments de code suivants:

# Version 1 (concaténation)
f.write(ch1 + ch2)

 

# Version 2 (opérations d'E/S séparées)
f.write(ch1)
f.write(ch2)

 

Si les deux chaînes sont petites, la première version pourrait offrir de bien meilleures performances en raison des coûts inhérents à l’exécution d’un appel système d’E/S.

D’autre part, si les deux chaînes de caractères sont grandes, la seconde version peut être plus efficace, car elle évite de produire un grand résultat temporaire et de copier de grands blocs de mémoire.

Encore une fois, il faut souligner qu’il s’agit d’une chose qu’il faudrait étudier par rapport à vos propres données afin de déterminer laquelle est la plus performante.

Enfin, si vous écrivez du code qui construit des sorties à partir de beaucoup de petites chaînes de caractères, vous pourriez envisager d’écrire ce code comme une fonction générateur, en utilisant l’instruction yield pour émettre des fragments. Par exemple:

def exemple():
   yield 'La'
   yield 'vie'
   yield 'est'
   yield 'belle.'

 

Ce qui est intéressant dans cette approche, c’est qu’elle ne fait aucune supposition sur la façon dont les fragments doivent être assemblés. Par exemple, vous pourriez simplement joindre les fragments en utilisant la méthode join() :

texte = ''.join(exemple())

 

Ou vous pouvez rediriger les fragments vers les E/S :

for partie in exemple():
    f.write(partie)

 

Ou vous pourriez imaginer une sorte de système hybride qui combine intelligemment les opérations d’E/S:

def combiner(source, taillemax):
   parties = []
   taille = 0
   for partie in source:
      parties.append(partie)
      taille += len(partie)
      if taille > taillemax:
         yield ''.join(parties)
         parties = []
         taille = 0
      yield ''.join(parties)

   for partie in combiner(exemple(), 32768):
      f.write(partie)

 

Le point clé est que la fonction originale du générateur n’a pas besoin de connaître les détails précis. Il ne fait que fournir les morceaux.

LAISSER UN COMMENTAIRE

Please enter your comment!
Please enter your name here