Python string.join (lista) na matriz de objetos em vez da matriz de cadeias


291

No Python, eu posso fazer:

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

Existe alguma maneira fácil de fazer o mesmo quando tenho uma 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

Ou tenho que recorrer a um loop for?

Respostas:


432

Você poderia usar uma compreensão de lista ou uma expressão geradora:

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

3
ou uma expressão geradora: ',' .join (str (x) para x na lista)
dF.

1
alguma idéia sobre qual deles seria mais rápido?
gozzilli

Minhas experiências dizem que a compreensão da lista pode ser 60% mais rápida em listas pequenas (a experiência é executada 10 ^ 6 vezes em uma lista de três objetos (s)). No entanto, seu desempenho é semelhante em grandes listas (a segunda experiência é executada uma vez em uma lista de 10 ^ 7 objetos ()).
gozzilli

3
para uma boa aceleração de 30% (acima da expressão do gerador acima), pode-se usar a mapexpressão supostamente menos legível (abaixo).
K3 --- rnc

2
Essa resposta é objetivamente pior que a mapsolução.
PascalVKooten

96

O construtor de string interno chamará automaticamente obj.__str__:

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

1
map () não altera a lista, é equivalente a [str (o) para o na lista]
dF.

11
+1: o mapa é uma boa abordagem; "alterar a lista" não é um comentário preciso.
S.Lott

2
(outro) +1 .. mapa não é menos legível, só precisa saber o que a função de mapa faz
lapax

1
@ Michael Não está correto. reducefoi o que foi removido, porque geralmente deixava as pessoas adivinhando e, portanto, não era "pitônico". mappor outro lado, não é um problema.
PascalVKooten

1
(outro) +1: vindo do mundo Perl, isso é a coisa mais comum no universo: join ("sep", lista) - e todos os elementos da lista são convertidos em suas representações de string. Eu tenho realmente lutado para encontrar uma solução em python.
Jason

2

outra solução é substituir o operador de junção da classe str.

Vamos definir uma nova classe my_string da seguinte maneira

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

Então você pode fazer

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

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

print comma.join(list)

e você recebe

name,name,name

BTW, usando list como nome da variável, você está redefinindo a classe da lista (palavra-chave)! De preferência, use outro nome de identificador.

Espero que você ache minha resposta útil.


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.