Puisque la chaîne de caractères de Python ne peut pas être modifiée, je me demandais comment concaténer une chaîne de caractères plus efficacement ?
Je peux écrire comme ça :
s += stringfromelsewhere
ou comme ça :
s = []
s.append(somestring)
later
s = ''.join(s)
En écrivant cette question, j'ai trouvé un bon article traitant du sujet.
http://www.skymind.com/~ocrow/python_string/
Mais il s'agit de Python 2.x. La question est donc de savoir si quelque chose a changé dans Python 3 ?
Si vous concaténer un grand nombre de valeurs, alors aucun des deux. L'ajout d'une liste est coûteux. Vous pouvez utiliser StringIO pour cela. Surtout si vous la construisez sur un grand nombre d'opérations.
from cStringIO import StringIO
# python3: from io import StringIO
buf = StringIO()
buf.write('foo')
buf.write('foo')
buf.write('foo')
buf.getvalue()
# 'foofoofoo'
Si vous avez déjà une liste complète qui vous a été retournée par une autre opération, alors utilisez simplement la commande '' ;.join(aList)
.
Extrait de la FAQ python : [Quel est le moyen le plus efficace de concaténer plusieurs chaînes de caractères ensemble ?][1]
Les objets str et bytes sont immuables, par conséquent, concaténer plusieurs chaînes de caractères est inefficace car chaque concaténation crée un nouvel objet. objet. Dans le cas général, le coût total d'exécution est quadratique par rapport à la longueur totale de la chaîne. la longueur totale de la chaîne.
Pour accumuler de nombreux objets str, l'idiome recommandé est de les placer dans une liste et d'appeler str.join() à la fin :
chunks = [] for s in my_strings : chunks.append(s) résultat = '' ;.join(chunks)
(un autre idiome raisonnablement efficace consiste à utiliser io.StringIO)
Pour accumuler de nombreux objets octets, l'idiome recommandé est d'étendre un objet bytearray en utilisant la concaténation sur place (l'opérateur +=) :
resultat = bytearray() for b in my_bytes_objects : resultat += b
Edit : J'ai été stupide et j'ai collé les résultats à l'envers, faisant croire que l'ajout à une liste était plus rapide que cStringIO. J'ai également ajouté des tests pour bytearray/str concat, ainsi qu'une deuxième série de tests utilisant une liste plus grande avec des chaînes plus grandes. (python 2.7.3)
exemple de test en python pour de grandes listes de chaînes de caractères
try:
from cStringIO import StringIO
except:
from io import StringIO
source = ['foo']*1000
%%timeit buf = StringIO()
for i in source:
buf.write(i)
final = buf.getvalue()
# 1000 loops, best of 3: 1.27 ms per loop
%%timeit out = []
for i in source:
out.append(i)
final = ''.join(out)
# 1000 loops, best of 3: 9.89 ms per loop
%%timeit out = bytearray()
for i in source:
out += i
# 10000 loops, best of 3: 98.5 µs per loop
%%timeit out = ""
for i in source:
out += i
# 10000 loops, best of 3: 161 µs per loop
## Repeat the tests with a larger list, containing
## strings that are bigger than the small string caching
## done by the Python
source = ['foo']*1000
# cStringIO
# 10 loops, best of 3: 19.2 ms per loop
# list append and join
# 100 loops, best of 3: 144 ms per loop
# bytearray() +=
# 100 loops, best of 3: 3.8 ms per loop
# str() +=
# 100 loops, best of 3: 5.11 ms per loop
Bien que datant un peu, [Code Like a Pythonista : Idiomatic Python][1] recommande join()
plutôt que +
[dans cette section][2]. Tout comme [PythonSpeedPerformanceTips][3] dans sa section sur la [concaténation de chaînes de caractères][4], avec l'avertissement suivant :
L'exactitude de cette section est contestée en ce qui concerne les versions ultérieures de Python. versions ultérieures de Python. Dans CPython 2.5, la concaténation de chaînes de caractères est assez rapide, bien que cela puisse être le cas dans certaines versions. rapide, bien que cela puisse ne pas s'appliquer de la même manière à d'autres implémentations Python. Voir ConcatenationTestCode pour une discussion.
[1] : http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html [2] : http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#building-stringues-from-substrings [3] : http://wiki.python.org/moin/PythonSpeed/PerformanceTips/ [4] : http://wiki.python.org/moin/PythonSpeed/PerformanceTips/#String_Concatenation