Convierte una lista de caracteres en una cadena

Respuestas:

585

Use el joinmétodo de la cadena vacía para unir todas las cadenas junto con la cadena vacía en el medio, así:

>>> a = ['a', 'b', 'c', 'd']
>>> ''.join(a)
'abcd'
Daniel Stutzbach
fuente
1
¿Cómo puedo agregar espacios entre los personajes? de todos modos para hacerlo sin iterar todo el asunto?
clifgray
18
acaba de hacer ' '.join(list)con un espacio entre las comillas
clifgray
Lo bueno de esto es que puede usar '\ n'.join (a) si desea escribir una lista en un txt con nuevas líneas para cada elemento
Norfeldt
28
Para aclarar: "".join(['a','b','c'])medios Join all elements of the array, separated by the string "". De la misma manera, " hi ".join(["jim", "bob", "joe"])creará "jim hi bob hi joe".
Jack
39

Esto funciona en muchos lenguajes populares como JavaScript y Ruby, ¿por qué no en Python?

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

Por extraño que parezca, en Python el joinmétodo está en la strclase:

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

¿Por qué joinno hay un método en el listobjeto como en JavaScript u otros lenguajes de script populares? Es un ejemplo de cómo piensa la comunidad Python. Dado que join está devolviendo una cadena, debe colocarse en la clase de cadena, no en la clase de lista, por lo que el str.join(list)método significa: unir la lista en una nueva cadena usando strcomo separador (en este caso stres una cadena vacía).

De alguna manera llegué a amar esta forma de pensar después de un tiempo. Me puedo quejar de muchas cosas en el diseño de Python, pero no de su coherencia.

Paulo Scardine
fuente
1
La razón principal por la que unirse es un método de cadena en lugar de un método de lista es que acepta cualquier iterable , no solo una lista. Puede usar expresiones generadoras, diccionarios, conjuntos, vistas de varios tipos, etc. Por lo tanto, es mucho más flexible que la operación de combinación de matrices en la mayoría de los idiomas.
rosuav
Estaba comparando Python string.join()con la mayoría de las colecciones que tienen un join()método en muchos lenguajes dinámicos. Con respecto a los iterables, supongo que no es un problema para tales lenguajes porque es tan fácil (y legible) encerrar el iterable en un constructor de colecciones y una cadena en el join()método.
Paulo Scardine
Sí, suponiendo que tengan listas perezosas (estilo Haskell) o que se sienta cómodo fusionando la lista en la memoria antes de comenzar. Mi punto es que la forma de actuar de Python no es arbitraria, tiene muy buena justificación.
rosuav
1
No es arbitrario, es una decisión de diseño para evitar la contaminación del espacio de nombres en cada clase. :-)
Paulo Scardine
Exactamente. Además, no todos son incluso clases: "iterable" es un protocolo, no una clase. Puede filtrar, asignar, unir, etc., usando cualquier iterable.
rosuav
15

Si su intérprete de Python es antiguo (1.5.2, por ejemplo, que es común en algunas distribuciones de Linux más antiguas), es posible que no tenga join()disponible como método en ningún objeto de cadena antiguo, y en su lugar deberá usar el módulo de cadena. Ejemplo:

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

try:
    b = ''.join(a)

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

La cadena bserá 'abcd'.

Kyle
fuente
10

Esta puede ser la forma más rápida:

>> from array import array
>> a = ['a','b','c','d']
>> array('B', map(ord,a)).tostring()
'abcd'
bigeagle
fuente
44
@WinstonEwert sí, ayer estaba escribiendo un programa que tiene que hacer tal cosa, y yo como punto de referencia algunas de las formas para la realización de esta línea cuenta en mi programa, los espectáculos resultado es un 20% más rápido que''.join(['a','b','c'])
bigeagle
2
Mi propia muestra de referencia se une para ser 7 veces más rápido. pastebin.com/8nSc5Ek1 . ¿Te importa compartir tu punto de referencia?
Winston Ewert
1
@ WinstonEwert Tienes razón. He encontrado la razón de esto: en mi programa, recibo una lista de int de la red y luego la convierto en una cadena donde no map(ord,a)es necesario, pero unir las necesidades map(chr,a). Aquí está mi punto de referencia pastebin.com/1sKFm8ma
bigeagle
15
Optimización prematura. Esto es muy difícil de leer y entender lo que está sucediendo. A menos que el usuario NECESITA rendimiento en la operación, un simple ''.join()es mucho más legible.
Luiz Damim
55
no estoy de acuerdo: los programadores deben tener en cuenta los métodos más rápidos para tales cosas. una sola operación simple que lleva un poco más de tiempo no es gran cosa. Sin embargo, así es como casi todos los programas escritos terminan hinchados y ocupando demasiados recursos. Cuando no nos acostumbramos a hacer las cosas lo más esbeltas posible, terminamos con un mundo que es ... bueno, como Windows Vista o Upstart en Linux son buenos ejemplos de muchos atajos pequeños que conducen a 'hincharse y flotar', como en muerto en el agua. ambos son feos también. ¿por qué no usar str (). join (a) que es 100% expresivo imfho ..
osirisgothra
4

La función de reducción también funciona

import operator
h=['a','b','c','d']
reduce(operator.add, h)
'abcd'
cce
fuente
1
Siempre me molesta que los operadores no sean ciudadanos de primera clase por derecho propio. En el esquema, por ejemplo, eso sería (reducir + h)
Brian Minton
En esquema, (reduce + '' h)o (apply + h)funcionaría. Pero, de nuevo, en Python, el operador add toma exactamente 2 operandos, de ahí la necesidad de reducir. De lo contrario, podría hacerlo operator.add(*h), ya que applyha quedado oficialmente en desuso en Python a favor de la sintaxis de llamada extendida (también conocido como en.wikipedia.org/wiki/Variadic_function )
Brian Minton
3

Si la lista contiene números, puede usar map()con join().

P.ej:

>>> arr = [3, 30, 34, 5, 9]
>>> ''.join(map(str, arr))
3303459
yask
fuente
en realidad es más pitónico de usar''.join([str(i) for i in arr])
user1767754
@ user1767754 Bueno, Guido prefiere ese estilo, pero no hay absolutamente nada de malo en usar la función de mapa.
itsbruce
2
h = ['a','b','c','d','e','f']
g = ''
for f in h:
    g = g + f

>>> g
'abcdef'
Cuenta
fuente
66
Esto sería bastante lento. El uso ''.join(h)superaría con creces su método de adición uno por uno.
Martijn Pieters
1
en 'la' biblia de Python (esa 1400+ página uno), en muchos lugares nos dice que esto es incorrecto y debe evitarse siempre que sea posible. También es una marca dolorosamente obvia del principiante de Python desinformado (para no insultar la funcionalidad ... bueno) puede funcionar, pero escuchará "No hagas esto" de aproximadamente 5000 personas por hacerlo.
osirisgothra
2

Además de str.joincuál es la forma más natural, una posibilidad es usar io.StringIOy abusar writelinesde escribir todos los elementos de una vez:

import io

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

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

huellas dactilares:

abcd

Cuando se usa este enfoque con una función generadora o un iterable que no es un tupleo un list, guarda la creación de la lista temporal que joinhace para asignar el tamaño correcto de una vez (y una lista de cadenas de 1 carácter es muy costosa en cuanto a memoria )

Si tiene poca memoria y tiene un objeto vagamente evaluado como entrada, este enfoque es la mejor solución.

Jean-François Fabre
fuente
0

También podría usar operator.concat()así:

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

Si está utilizando Python 3, debe anteponer:

>>> from functools import reduce

ya que la construcción reduce()se ha eliminado de Python 3 y ahora vive en ella functools.reduce().

Tonechas
fuente