Python string.join (lista) en la matriz de objetos en lugar de la matriz de cadenas


291

En Python, puedo hacer:

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

¿Hay alguna manera fácil de hacer lo mismo cuando tengo una lista de objetos?

>>> class Obj:
...     def __str__(self):
...         return 'name'
...
>>> list = [Obj(), Obj(), Obj()]
>>> ', '.join(list)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected string, instance found

¿O tengo que recurrir a un bucle for?

Respuestas:


432

En su lugar, podría usar una comprensión de lista o una expresión generadora:

', '.join([str(x) for x in list])  # list comprehension
', '.join(str(x) for x in list)    # generator expression

3
o una expresión generadora: ',' .join (str (x) para x en la lista)
dF.

1
alguna idea sobre cuál de ellos sería más rápido?
gozzilli

Mis experimentos dicen que la comprensión de la lista puede ser un 60% más rápida en listas pequeñas (el experimento se ejecuta 10 ^ 6 veces en una lista de tres objetos). Sin embargo, su rendimiento es similar en las grandes listas (segundo experimento realizado una vez en una lista de 10 ^ 7 objetos ()).
gozzilli

3
para un buen 30% de aceleración (sobre la expresión del generador arriba), se puede usar la mapexpresión supuestamente menos legible (abajo).
K3 --- rnc

2
Esta respuesta es objetivamente peor que la mapsolución.
PascalVKooten

96

El constructor de cadenas incorporado llamará automáticamente obj.__str__:

''.join(map(str,list))

1
map () no cambia la lista, es equivalente a [str (o) para o en la lista]
dF.

11
+1: el mapa es un buen enfoque; "cambiar la lista" no es un comentario exacto.
S.Lott

2
(otro) +1 ... el mapa no es menos legible, solo necesito saber qué hace la función del mapa
lapax

1
@Michael No es correcto. reducefue el que se eliminó, porque generalmente dejaba a la gente adivinando y, por lo tanto, no era "pitónico". mapPor otro lado, no es un problema.
PascalVKooten

1
(otro) +1: viniendo del mundo de Perl, esto es lo más común en el universo: unirse ("sep", lista) - y todos los elementos de la lista se convierten en sus representaciones de cadena. Realmente he estado luchando por encontrar una solución en Python.
Jason

2

Otra solución es anular el operador de unión de la clase str.

Definamos una nueva clase my_string de la siguiente manera

class my_string(str):
    def join(self, l):
        l_tmp = [str(x) for x in l]
        return super(my_string, self).join(l_tmp)

Entonces puedes hacer

class Obj:
    def __str__(self):
        return 'name'

list = [Obj(), Obj(), Obj()]
comma = my_string(',')

print comma.join(list)

y obtienes

name,name,name

Por cierto, al usar la lista como nombre de variable, está redefiniendo la clase de lista (palabra clave) Preferiblemente use otro nombre de identificador.

Espero que mi respuesta sea útil.


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.