2011-04-07 16 views
5

Ya he consultado this question on representing strings in Python pero mi pregunta es ligeramente diferente.Unirme a una lista de objetos python con el método __str__

Aquí está el código:

>>> class WeirdThing(object): 
...  def __init__(self): 
...   self.me = time.time() 
...  def __str__(self): 
...   return "%s" % self.me 
...  def __repr__(self): 
...   return ";%s;" % self.me 
... 
>>> weird_list = [WeirdThing(), WeirdThing(), WeirdThing()] 
>>> print weird_list 
[;1302217717.89;, ;1302217717.89;, ;1302217717.89;] 
>>> "\n".join(weird_list) 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
TypeError: sequence item 0: expected string, WeirdThing found 

Soy consciente de que esto funciona:

>>> "\n".join(str(wi) for wi in weird_list) 
'1302217717.89\n1302217717.89\n1302217717.89' 
>>> 

Sin embargo, sería bueno evitar hacer que cada vez que quieren unirse a los objetos entre sí. ¿Simplemente no es posible?

+0

Adelante e ignore el resultado de las funciones; esta podría ser cualquier clase con un método '__str__'. –

Respuesta

10

Tiene que torcer sus objetos antes de poder unirlos. Esto se debe a que str.join espera una serie de cadenas y debe darle una serie de cadenas.

Por el bien de menos tipeo a costa de la legibilidad, puede hacer "\n".join(map(str, list_of_things).

+0

Una alternativa sería usar una expresión de generador: ''\ n'.join ((str (x) para x en list_of_things))' – Wesley

+1

Eso es lo que el OP tenía en su publicación, que, creo, es la forma preferida sobre el uso del mapa. – DTing

+0

Gracias. Esperaba que hubiera alguna manera de hacer que esto implícito en la forma en que JavaScript llama automáticamente al método .toString() en un objeto cuando se utiliza como una cadena. Entonces, por supuesto, recordé: [Explícito es mejor que implícito.] (Http://www.python.org/dev/peps/pep-0020/) –

0

Usted técnicamente no se está uniendo a la lista de objetos de python, solo su representación de cadena.

>>> reduce(lambda x,y: "%s\n%s" % (x,y), weird_list) 
'1302226564.83\n1302226564.83\n1302226564.83' 
>>> 

Esto funciona así, pero no se ve más amable:

>>> a = "" 
>>> for x in weird_list: 
...  a+="%s\n" % x 
... 
>>> print a 
1302226564.83 
1302226564.83 
1302226564.83 

>>> 
2

probablemente no hay manera asombrosa.

def strjoin(glue, iterable): 
    return glue.join(str(s) for s in iterable) 
0

¿Funcionaría para usted si se ha añadido un método __add__? Por ejemplo,

from operator import add 
from random import randint 

class WeirdThing(object): 
    def __init__(self,me=None): 
     self.me = me if me else chr(randint(97,122)) 
    def __str__(self): 
     return "%s" % self.me 
    def __repr__(self): 
     return ";%s;" % self.me 
    def __add__(self,other): 
     new_me = add(str(self.me),str(other.me)) 
     return WeirdThing(new_me) 

weird_list = [WeirdThing(), WeirdThing(), WeirdThing()] 
print weird_list 

da,

[;y;, ;v;, ;u;] 

y esto,

strange_thing = reduce(add,weird_list) 
print strange_thing 

da,

yvu 
+0

'str.join()' tiene complejidad lineal, esto es cuadrático. Para cualquier longitud de lista, esto tendrá un rendimiento horrible de todas las cadenas intermedias temporales que se producen. – Duncan

1

" ... sería bueno para evitar hacer que cada tiempo ... "

¿Desea evitar repetir el mismo código varias veces? A continuación, utilice una función ;:

def join_as_str(alist): 
    return "\n".join(str(item) for item in alist) 
Cuestiones relacionadas