Convertir une liste de caractères en chaîne

415

Si j'ai une liste de caractères:

a = ['a','b','c','d']

Comment puis-je le convertir en une seule chaîne?

a = 'abcd'
non
la source
7
Lien vers une autre direction
Tobias Kienzler

Réponses:

585

Utilisez la joinméthode de la chaîne vide pour joindre toutes les chaînes avec la chaîne vide entre les deux, comme ceci:

>>> a = ['a', 'b', 'c', 'd']
>>> ''.join(a)
'abcd'
Daniel Stutzbach
la source
1
comment ajouter des espaces entre les personnages? de toute façon le faire sans répéter tout ça?
clifgray
18
il suffit de faire ' '.join(list)un espace entre les guillemets
clifgray
Une bonne chose à ce sujet est que vous pouvez utiliser '\ n'.join (a) si vous voulez écrire une liste dans un txt avec de nouvelles lignes pour chaque élément
Norfeldt
28
Pour clarifier: "".join(['a','b','c'])signifie Join all elements of the array, separated by the string "". De la même manière, " hi ".join(["jim", "bob", "joe"])va créer "jim hi bob hi joe".
Jack
39

Cela fonctionne dans de nombreux langages populaires comme JavaScript et Ruby, pourquoi pas en Python?

>>> ['a', 'b', 'c'].join('')
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'join'

Assez étrange, en Python, la joinméthode est sur la strclasse:

# this is the Python way
"".join(['a','b','c','d'])

Pourquoi joinn'y a- t -il pas une méthode dans l' listobjet comme en JavaScript ou dans d'autres langages de script populaires? C'est un exemple de la façon dont la communauté Python pense. Puisque join renvoie une chaîne, elle doit être placée dans la classe de chaîne, pas dans la classe de liste, donc la str.join(list)méthode signifie: joindre la liste dans une nouvelle chaîne en utilisant strcomme séparateur (dans ce cas, strc'est une chaîne vide).

D'une certaine manière, j'ai appris à aimer cette façon de penser après un certain temps. Je peux me plaindre de beaucoup de choses dans la conception Python, mais pas de sa cohérence.

Paulo Scardine
la source
1
La principale raison pour laquelle join est une méthode de chaîne plutôt qu'une méthode de liste est qu'elle accepte tout itérable , pas seulement une liste. Vous pouvez utiliser des expressions de générateur, des dictionnaires, des ensembles, des vues de différents types, etc. C'est donc beaucoup plus flexible que l'opération de jointure de tableau dans la plupart des langues.
rosuav
Je comparais Python string.join()avec la plupart des collections ayant une join()méthode dans de nombreux langages dynamiques. Concernant les itérables, je suppose que ce n'est pas un problème pour de telles langues car il est aussi facile (et lisible) d'inclure l'itérable dans un constructeur de collection et une chaîne dans la join()méthode.
Paulo Scardine
Oui, en supposant qu'ils ont des listes paresseuses (style Haskell) ou que vous êtes à l'aise avec la fusion de la liste en mémoire avant de commencer. Mon point est que la façon de faire de Python n'est pas arbitraire, elle a une très bonne justification.
rosuav
1
Ce n'est pas arbitraire, c'est une décision de conception pour éviter la pollution de l'espace de noms dans chaque classe. :-)
Paulo Scardine
Exactement. De plus, ce ne sont pas tous des classes paires - "itérable" est un protocole, pas une classe. Vous pouvez filtrer, mapper, rejoindre, etc., en utilisant n'importe quel itérable.
rosuav
15

Si votre interpréteur Python est ancien (1.5.2, par exemple, ce qui est courant sur certaines anciennes distributions Linux), il se peut que vous ne disposiez pas join()de méthode comme méthode sur un ancien objet chaîne, et vous devrez plutôt utiliser le module chaîne. Exemple:

a = ['a', 'b', 'c', 'd']

try:
    b = ''.join(a)

except AttributeError:
    import string
    b = string.join(a, '')

La chaîne bsera 'abcd'.

Kyle
la source
10

Cela peut être le moyen le plus rapide:

>> from array import array
>> a = ['a','b','c','d']
>> array('B', map(ord,a)).tostring()
'abcd'
bigeagle
la source
4
@WinstonEwert oui, hier, j'écrivais un programme qui doit faire une telle chose, et j'ai comparé quelques façons pour que les performances de cette ligne comptent dans mon programme, le résultat montre qu'il est environ 20% plus rapide alors''.join(['a','b','c'])
bigeagle le
2
Mes propres émissions de référence se joignent pour être 7 fois plus rapides. pastebin.com/8nSc5Ek1 . Vous avez envie de partager votre référence?
Winston Ewert
1
@WinstonEwert Vous avez raison. J'ai trouvé la raison de ceci: dans mon programme, je récupère une liste d'int du réseau, puis la convertis en chaîne où cela map(ord,a)n'est pas nécessaire, mais joint les besoins map(chr,a). Voici mon benchmark pastebin.com/1sKFm8ma
bigeagle
15
Optimisation prématurée. C'est tellement difficile à lire et à comprendre ce qui se passe. Sauf si l'utilisateur a BESOIN de performances dans l'opération, un simple ''.join()est beaucoup plus lisible.
Luiz Damim
5
en désaccord - les programmeurs doivent garder à l'esprit les méthodes les plus rapides. une seule opération simple qui prend un peu plus de temps n'est pas grave. Cependant, c'est ainsi que presque tous les programmes écrits finissent par ballonnements et prennent trop de ressources. Lorsque nous ne nous habituons pas à rendre les choses aussi légères que possible, nous nous retrouvons avec un monde qui est comme ... eh bien, comme Windows Vista ou Upstart sous Linux sont de bons exemples de nombreux petits raccourcis menant à «ballonnement et flottement», comme dans les morts dans l'eau. ils sont tous les deux aussi laids. pourquoi ne pas utiliser str (). join (a) qui est 100% expressif imfho ..
osirisgothra
4

La fonction de réduction fonctionne également

import operator
h=['a','b','c','d']
reduce(operator.add, h)
'abcd'
cce
la source
1
Cela me dérange toujours que les opérateurs ne soient pas des citoyens de première classe à part entière. Dans le schéma, par exemple, ce serait (réduire + h)
Brian Minton
Dans le schéma, (reduce + '' h)ou (apply + h)fonctionnerait. Mais là encore, en Python, l'opérateur add prend exactement 2 opérandes, d'où la nécessité de réduire. Sinon, vous pourriez le faire operator.add(*h), car applya été officiellement déconseillé en Python au profit de la syntaxe d'appel étendue (aka en.wikipedia.org/wiki/Variadic_function )
Brian Minton
3

Si la liste contient des nombres, vous pouvez utiliser map()avec join().

Par exemple:

>>> arr = [3, 30, 34, 5, 9]
>>> ''.join(map(str, arr))
3303459
yask
la source
il est en fait plus pythonique à utiliser''.join([str(i) for i in arr])
user1767754
@ user1767754 Eh bien, Guido préfère ce style mais il n'y a absolument rien de mal à utiliser la fonction de carte.
itsbruce
2
h = ['a','b','c','d','e','f']
g = ''
for f in h:
    g = g + f

>>> g
'abcdef'
Facture
la source
6
Ce serait assez lent. L'utilisation ''.join(h)dépasserait de loin votre méthode d'ajout un par un.
Martijn Pieters
1
dans «la» Bible en python (celle de 1400+ page 1), dans de nombreux endroits, cela nous dit que c'est mal de le faire et qu'il faut l'éviter autant que possible. C'est aussi une marque de commerce douloureusement évidente du débutant en python non informé (pour ne pas insulter la fonctionnalité ... eh bien) cela peut fonctionner mais vous entendrez "Ne faites pas cela" d'environ 5000 personnes pour le faire.
osirisgothra
2

en plus str.joinqui est le moyen le plus naturel, une possibilité est d'utiliser io.StringIOet d'abuser writelinespour écrire tous les éléments en une seule fois:

import io

a = ['a','b','c','d']

out = io.StringIO()
out.writelines(a)
print(out.getvalue())

impressions:

abcd

Lorsque vous utilisez cette approche avec une fonction de générateur ou un itérable qui n'est pas un tupleou un list, il enregistre la création de liste temporaire qui joinalloue la bonne taille en une seule fois (et une liste de chaînes à 1 caractère coûte très cher en mémoire ).

Si vous manquez de mémoire et que vous avez en entrée un objet évalué paresseusement, cette approche est la meilleure solution.

Jean-François Fabre
la source
0

Vous pouvez également utiliser operator.concat()comme ceci:

>>> from operator import concat
>>> a = ['a', 'b', 'c', 'd']
>>> reduce(concat, a)
'abcd'

Si vous utilisez Python 3, vous devez ajouter:

>>> from functools import reduce

depuis que la fonction intégrée reduce()a été supprimée de Python 3 et vit maintenant dans functools.reduce().

Tonechas
la source