Como você criaria uma string separada por vírgula a partir de uma lista de strings?

528

Qual seria sua maneira preferida de concatenar seqüências de caracteres de uma sequência, de modo que entre cada dois pares consecutivos uma vírgula seja adicionada. Ou seja, como você mapeia, por exemplo, ['a', 'b', 'c']para 'a,b,c'? (Os casos ['s']e []devem ser mapeados para 's'e '', respectivamente.)

Normalmente, acabo usando algo como ''.join(map(lambda x: x+',',l))[:-1], mas também me sentindo um pouco insatisfeito.

Mweerden
fonte

Respostas:

969
my_list = ['a', 'b', 'c', 'd']
my_string = ','.join(my_list)
'a,b,c,d'

Isso não funcionará se a lista contiver números inteiros


E se a lista contiver tipos que não sejam de seqüência de caracteres (como números inteiros, flutuadores, bools, Nenhum), faça:

my_string = ','.join(map(str, my_list)) 
Mark Biek
fonte
Observe que se você estiver usando o python 2.7 (o que você não deveria agora), o uso de str gerará uma exceção se algum item da lista tiver unicode.
kroiz
75

Por que a map/ lambdamagia? Isso não funciona?

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

>>> print(','.join(['a']))
a

Caso haja números na lista, você pode usar a compreensão da lista:

>>> ','.join([str(x) for x in foo])

ou uma expressão geradora:

>>> ','.join(str(x) for x in foo)
jmanning2k
fonte
18

",".join(l)não funcionará para todos os casos. Eu sugiro usar o módulo csv com StringIO

import StringIO
import csv

l = ['list','of','["""crazy"quotes"and\'',123,'other things']

line = StringIO.StringIO()
writer = csv.writer(line)
writer.writerow(l)
csvcontent = line.getvalue()
# 'list,of,"[""""""crazy""quotes""and\'",123,other things\r\n'
Ricky
fonte
Não existe StringIOno Python 3
Ron Kalian
4
@RonKalian Use from io import StringIOem Python 3
Kevin Ashcraft
13

Aqui está uma solução alternativa no Python 3.0 que permite itens de lista que não são de cadeia:

>>> alist = ['a', 1, (2, 'b')]
  • uma maneira padrão

    >>> ", ".join(map(str, alist))
    "a, 1, (2, 'b')"
    
  • a solução alternativa

    >>> import io
    >>> s = io.StringIO()
    >>> print(*alist, file=s, sep=', ', end='')
    >>> s.getvalue()
    "a, 1, (2, 'b')"
    

NOTA: O espaço após a vírgula é intencional.

jfs
fonte
11

Você não quer apenas:

",".join(l)

Obviamente, fica mais complicado se você precisar citar / escapar vírgulas etc. nos valores. Nesse caso, eu sugeriria olhar o módulo csv na biblioteca padrão:

https://docs.python.org/library/csv.html

Douglas Leeder
fonte
10

@Peter Hoffmann

O uso de expressões geradoras também beneficia a produção de um iterador, mas economiza a importação de iteróis. Além disso, as compreensões de lista são geralmente preferidas para mapear, portanto, eu esperaria que expressões de gerador fossem preferidas ao imap.

>>> l = [1, "foo", 4 ,"bar"]
>>> ",".join(str(bit) for bit in l)
'1,foo,4,bar' 
Aaron Maenpaa
fonte
7
>>> my_list = ['A', '', '', 'D', 'E',]
>>> ",".join([str(i) for i in my_list if i])
'A,D,E'

my_listpode conter qualquer tipo de variável. Isso evita o resultado 'A,,,D,E'.

Shameem
fonte
4
l=['a', 1, 'b', 2]

print str(l)[1:-1]

Output: "'a', 1, 'b', 2"
AlvaroAV
fonte
1
Eu acho que você deve salientar que, diferentemente das outras soluções nesta página, você também cita as strings.
Mrdevlar
3

@ jmanning2k usando uma compreensão de lista tem a desvantagem de criar uma nova lista temporária. A melhor solução seria usar itertools.imap, que retorna um iterador

from itertools import imap
l = [1, "foo", 4 ,"bar"]
",".join(imap(str, l))
Peter Hoffmann
fonte
Esta solução não cumpre os requisitos de não adicionar vírgula extra para cadeia vazia e adicionar um 'Nenhum' com NenhumTipo.
Roberto
verificar str.join o trabalho mais rápido com listem comparação com gerador
Grijesh Chauhan
3

Aqui está um exemplo com lista

>>> myList = [['Apple'],['Orange']]
>>> myList = ','.join(map(str, [i[0] for i in myList])) 
>>> print "Output:", myList
Output: Apple,Orange

Mais preciso:-

>>> myList = [['Apple'],['Orange']]
>>> myList = ','.join(map(str, [type(i) == list and i[0] for i in myList])) 
>>> print "Output:", myList
Output: Apple,Orange

Exemplo 2: -

myList = ['Apple','Orange']
myList = ','.join(map(str, myList)) 
print "Output:", myList
Output: Apple,Orange

fonte
1
Esta pergunta era sobre listas, não listas de listas .
Eero Aaltonen
@EeroAaltonen Atualizei Minha resposta, Obrigado por me apontar para a direita.
1

Eu diria que a csvbiblioteca é a única opção sensata aqui, pois foi criada para lidar com todos os casos de uso do csv, como vírgulas em uma string, etc.

Para gerar uma lista lpara um arquivo .csv:

import csv
with open('some.csv', 'w', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(l)  # this will output l as a single row.  

Também é possível usar writer.writerows(iterable)a saída de várias linhas para csv.

Este exemplo é compatível com o Python 3, pois a outra resposta usada aqui StringIOé o Python 2.

Ron Kalian
fonte
Mas isso não é muito complicado / complicado em comparação com outras respostas?
Sreenikethan I
0

A menos que esteja faltando alguma coisa, ','.join(foo)faça o que você está pedindo.

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

(editar: e como jmanning2k aponta,

','.join([str(x) for x in foo])

é mais seguro e bastante pitonico, embora a cadeia resultante seja difícil de analisar se os elementos puderem conter vírgulas - nesse ponto, você precisa de toda a potência do csvmódulo, como Douglas aponta em sua resposta.)

David Singer
fonte
-2

Meus dois centavos. Eu gosto mais simples de um código de uma linha em python:

>>> from itertools import imap, ifilter
>>> l = ['a', '', 'b', 1, None]
>>> ','.join(imap(str, ifilter(lambda x: x, l)))
a,b,1
>>> m = ['a', '', None]
>>> ','.join(imap(str, ifilter(lambda x: x, m)))
'a'

É pythonic, funciona para strings, números, None e string vazia. É curto e satisfaz os requisitos. Se a lista não contiver números, podemos usar esta variação mais simples:

>>> ','.join(ifilter(lambda x: x, l))

Além disso, essa solução não cria uma nova lista, mas usa um iterador, como @Peter Hoffmann apontou (obrigado).

Roberto
fonte
Isso é supérfluo. A resposta aceita é simples, direta e claramente a melhor solução. Fornecer alternativas excessivamente complexas é uma perda de tempo inútil. Se você está apenas tentando educar sobre outros recursos do idioma quando já há respostas viáveis, está fazendo a mesma coisa pela qual me recusou.
clearlight 25/02