Python string.join (elenco) sull'array di oggetti anziché sull'array di stringhe


291

In Python, posso fare:

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

C'è un modo semplice per fare lo stesso quando ho un elenco di oggetti?

>>> 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 devo ricorrere a un ciclo for?

Risposte:


432

È possibile utilizzare invece una comprensione dell'elenco o un'espressione del generatore:

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

3
o un'espressione del generatore: ',' .join (str (x) per x nell'elenco)
dF.

1
qualche idea su quale di loro sarebbe più veloce?
gozzilli,

I miei esperimenti dicono che la comprensione dell'elenco può essere un buon 60% più veloce su piccoli elenchi (l'esperimento viene eseguito 10 ^ 6 volte su un elenco di tre oggetti). Tuttavia, le loro prestazioni sono simili su grandi liste (il secondo esperimento viene eseguito una volta su una lista di 10 ^ 7 oggetti ()).
gozzilli,

3
per una buona accelerazione del 30% (sopra l'espressione del generatore sopra), si può usare l' mapespressione apparentemente meno leggibile (sotto).
K3 --- rnc,

2
Questa risposta è oggettivamente peggiore della mapsoluzione.
PascalVKooten,

96

Il costruttore di stringhe incorporato chiamerà automaticamente obj.__str__:

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

1
map () non cambia l'elenco, equivale a [str (o) per o in list]
dF.

11
+1: la mappa è un buon approccio; "modifica dell'elenco" non è un commento preciso.
S.

2
(altro) +1 .. la mappa non è meno leggibile, basta sapere cosa fa la funzione della mappa
lapax

1
@Michael Non corretto. reduceè stato quello che è stato rimosso, perché di solito lasciava indovinare le persone e quindi non era "pitonico". mapd'altra parte non è un problema.
PascalVKooten,

1
(un altro) +1: proveniente dal mondo Perl questa è la cosa più comune nell'universo: join ("sep", list) - e tutti gli elementi dell'elenco vengono convertiti nelle loro rappresentazioni di stringhe. Ho davvero avuto difficoltà a trovare una soluzione in Python.
Jason,

2

un'altra soluzione è quella di sovrascrivere l'operatore join della classe str.

Definiamo una nuova classe my_string come segue

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

Quindi puoi farlo

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

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

print comma.join(list)

e tu ottieni

name,name,name

A proposito, usando la lista come nome della variabile stai ridefinendo la classe della lista (parola chiave)! Utilizzare preferibilmente un altro nome identificativo.

Spero che troverai la mia risposta utile.


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.