Converti un elenco di caratteri in una stringa


Risposte:


585

Utilizzare il joinmetodo della stringa vuota per unire tutte le stringhe insieme alla stringa vuota in mezzo, in questo modo:

>>> a = ['a', 'b', 'c', 'd']
>>> ''.join(a)
'abcd'

1
come posso aggiungere spazi tra i personaggi? in ogni caso farlo senza iterare per intero?
clifgray,

18
basta fare ' '.join(list)uno spazio tra le virgolette
clifgray

Una cosa bella di questo è che puoi usare '\ n'.join (a) se vuoi scrivere una lista in un txt con nuove righe per ogni elemento
Norfeldt

28
Per chiarire: "".join(['a','b','c'])significa Join all elements of the array, separated by the string "". Allo stesso modo, " hi ".join(["jim", "bob", "joe"])creerà "jim hi bob hi joe".
Jack,

39

Funziona in molte lingue popolari come JavaScript e Ruby, perché non in Python?

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

Abbastanza strano, in Python il joinmetodo è sulla strclasse:

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

Perché joinun metodo listnell'oggetto non è simile a JavaScript o ad altri linguaggi di script popolari? È un esempio di come pensa la comunità Python. Poiché join restituisce una stringa, deve essere inserito nella classe stringa, non nella classe elenco, quindi il str.join(list)metodo significa: unire l'elenco in una nuova stringa usando strcome separatore (in questo caso strè una stringa vuota).

In qualche modo ho imparato ad amare questo modo di pensare dopo un po '. Posso lamentarmi di molte cose nel design di Python, ma non della sua coerenza.


1
Il motivo principale per cui join è un metodo stringa anziché un metodo elenco è che accetta qualsiasi iterabile , non solo un elenco. È possibile utilizzare espressioni del generatore, dizionari, set, viste di vario tipo e così via. Quindi è molto più flessibile dell'operazione di join dell'array nella maggior parte delle lingue.
Rosuav,

Stavo confrontando Python string.join()con la maggior parte delle raccolte con un join()metodo in molti linguaggi dinamici. Per quanto riguarda gli iterabili, suppongo che non sia un problema per tali lingue perché è altrettanto facile (e leggibile) racchiudere l'iterabile in un costruttore di raccolte e una catena nel join()metodo.
Paulo Scardine,

Sì, supponendo che abbiano liste pigre (stile Haskell) o che tu sia a tuo agio nel fondere l'elenco in memoria prima di iniziare. Il mio punto è che il modo di fare di Python non è arbitrario, ha un'ottima giustificazione.
Rosuav,

1
Non è arbitrario, è una decisione progettuale per evitare l'inquinamento dello spazio dei nomi in ogni classe. :-)
Paulo Scardine,

Esattamente. Inoltre, non tutte sono persino classi: "iterabile" è un protocollo, non una classe. Puoi filtrare, mappare, unire, ecc., Usando qualsiasi iterabile.
Rosuav,

15

Se il tuo interprete Python è vecchio (1.5.2, ad esempio, che è comune su alcune vecchie distribuzioni Linux), potresti non essere join()disponibile come metodo su qualsiasi vecchio oggetto stringa e dovrai invece usare il modulo stringa. Esempio:

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

try:
    b = ''.join(a)

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

La stringa bsarà 'abcd'.


10

Questo potrebbe essere il modo più veloce:

>> from array import array
>> a = ['a','b','c','d']
>> array('B', map(ord,a)).tostring()
'abcd'

4
@WinstonEwert sì, ieri stavo scrivendo un programma che ha bisogno di fare una cosa del genere, e ho fatto un benchmark di alcuni modi per le prestazioni di questa linea conta nel mio programma, il risultato mostra che è circa il 20% più veloce allora''.join(['a','b','c'])
bigeagle

2
Il mio benchmark mostra che l'adesione è 7 volte più veloce. pastebin.com/8nSc5Ek1 . Ti dispiace condividere il tuo benchmark?
Winston Ewert,

1
@WinstonEwert Hai ragione. Ho trovato il motivo per questo: nel mio programma ho recuperato un elenco di int dalla rete, quindi convertito in stringa dove map(ord,a)non è necessario, ma le esigenze di join map(chr,a). Ecco il mio benchmark pastebin.com/1sKFm8ma
bigeagle

15
Ottimizzazione prematura. È molto difficile da leggere e capire cosa sta succedendo. A meno che l'utente NON BISOGNA delle prestazioni nell'operazione, un semplice ''.join()è molto più leggibile.
Luiz Damim,

5
non sono d'accordo - i programmatori devono tenere a mente i metodi più veloci per queste cose. una singola semplice operazione che richiede un po 'più di tempo non è un grosso problema. Tuttavia, è così che praticamente tutti i programmi scritti finiscono per gonfiarsi e assorbire troppe risorse. Quando non ci prendiamo l'abitudine di rendere le cose il più snelle possibile, finiamo con un mondo che è come ... beh, come Windows Vista o Upstart in Linux sono buoni esempi di molte scorciatoie che portano a 'gonfia e galleggia', come in un morto nell'acqua. sono anche entrambi brutti. perché non usare str (). join (a) che è imfho espressivo al 100% ..
osirisgothra

4

La funzione di riduzione funziona anche

import operator
h=['a','b','c','d']
reduce(operator.add, h)
'abcd'

1
Mi da sempre fastidio che gli operatori non siano cittadini di prima classe a pieno titolo. Nello schema, ad esempio, sarebbe (ridurre + h)
Brian Minton il

In schema, (reduce + '' h)o (apply + h)avrebbe funzionato. Ma poi di nuovo, in Python, l'operatore add prende esattamente 2 operandi, quindi la necessità di ridurre. Altrimenti, potresti farlo operator.add(*h), dato che applyè stato ufficialmente deprecato in Python a favore della sintassi estesa delle chiamate (aka en.wikipedia.org/wiki/Variadic_function )
Brian Minton,

3

Se l'elenco contiene numeri, è possibile utilizzare map()con join().

Per esempio:

>>> arr = [3, 30, 34, 5, 9]
>>> ''.join(map(str, arr))
3303459

in realtà è più pythonic da usare''.join([str(i) for i in arr])
user1767754

@ user1767754 Bene, Guido preferisce quello stile ma non c'è assolutamente nulla di sbagliato nell'usare la funzione mappa.
itsbruce

2
h = ['a','b','c','d','e','f']
g = ''
for f in h:
    g = g + f

>>> g
'abcdef'

6
Questo sarebbe piuttosto lento. L'utilizzo ''.join(h)supererebbe di gran lunga il metodo di aggiunta uno a uno.
Martijn Pieters

1
nella 'python' bibbia (quella 1400+ pagina uno), in molti posti ci dice che questo è sbagliato da fare e deve essere evitato quando possibile. È anche un marchio dolorosamente ovvio del principiante non informato di Python (per non insultare la funzionalità ... beh) potrebbe funzionare ma sentirai "Non farlo" da circa 5000 persone per averlo fatto.
Osirisgothra,

2

oltre a str.joinquale è il modo più naturale, una possibilità è quella di usare io.StringIOe abusare writelinesper scrivere tutti gli elementi in una volta sola:

import io

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

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

stampe:

abcd

Quando si utilizza questo approccio con una funzione del generatore o un iterabile che non è un tupleo un list, si salva la creazione dell'elenco temporaneo che joinconsente di allocare la giusta dimensione in una volta (e un elenco di stringhe di 1 carattere è molto costoso in termini di memoria ).

Se hai poca memoria e hai un oggetto valutato pigramente come input, questo approccio è la soluzione migliore.


0

Puoi anche usare operator.concat()così:

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

Se stai usando Python 3 devi anteporre:

>>> from functools import reduce

da quando il builtin reduce()è stato rimosso da Python 3 e ora vive in functools.reduce().

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.