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.

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)) 

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)

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'

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.



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' 

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'.


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

print str(l)[1:-1]

Output: "'a', 1, 'b', 2"

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))

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

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.


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.)


-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).


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
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.