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'

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.


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'.


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'

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'

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

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'

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.


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().

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.