Como você criaria uma string separada por vírgula a partir de uma lista de strings?
Pergunta
Qual seria a sua maneira preferida de concatenar strings de uma sequência de forma que entre cada dois pares consecutivos seja adicionada uma vírgula.Ou seja, como você mapeia, por exemplo, [ 'a', 'b', 'c' ]
para 'a,b,c'
?(Os casos [ s ]
e []
deve ser mapeado para s
e ''
, respectivamente.)
Geralmente acabo usando algo como ''.join(map(lambda x: x+',',l))[:-1]
, mas também se sentindo um tanto insatisfeito.
Editar:Estou envergonhado e feliz que a solução seja tão simples.Obviamente não tenho a menor ideia do que estou fazendo.(Eu provavelmente precisei de concatenação "simples" no passado e de alguma forma memorizei s.join([e1,e2,...])
como uma abreviatura para s+e1+e2+...
.)
Solução
myList = ['a','b','c','d']
myString = ",".join(myList )
Isso não funcionará se a lista contiver números.
Como Ricardo Reis sugerido, se contiver tipos que não sejam string (como inteiros, flutuantes, bools, Nenhum), faça:
myList = ','.join(map(str, myList))
Outras dicas
Por que a magia do mapa/lambda?Isso não funciona?
>>>foo = [ 'a', 'b', 'c' ]
>>>print ",".join(foo)
a,b,c
>>>print ",".join([])
>>>print ",".join(['a'])
a
Editar:@mark-biek aponta o caso dos números.Talvez a compreensão da lista:
>>>','.join([str(x) for x in foo])
é mais "pitônico".
Editar2:Obrigado pelas sugestões.Usarei o gerador em vez da compreensão da lista no futuro.
>>>','.join(str(x) for x in foo)
",".join(l)
não funcionará para todos os casos.Eu sugeriria 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'
Aqui está uma solução alternativa em Python 3.0 que permite itens de lista sem string:
>>> 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')"
OBSERVAÇÃO:O espaço após a vírgula é intencional.
@Peter Hoffmann
O uso de expressões geradoras tem a vantagem de também produzir um iterador, mas economiza a importação de itertools.Além disso, as compreensões de lista geralmente são preferidas ao mapeamento, portanto, esperaria que as expressões geradoras fossem preferidas ao imap.
>>> l = [1, "foo", 4 ,"bar"]
>>> ",".join(str(bit) for bit in l)
'1,foo,4,bar'
Você não quer apenas:
",".join(l)
Obviamente fica mais complicado se você precisar citar/escapar vírgulas etc. nos valores.Nesse caso, sugiro olhar o módulo csv na biblioteca padrão:
>>> my_list = ['A', '', '', 'D', 'E',]
>>> ",".join([str(i) for i in my_list if i])
'A,D,E'
my_list
pode conter qualquer tipo de variáveis.Isso evita o resultado 'A,,,D,E'
.
@ jmanning2k usar 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))
para converter uma lista contendo números, faça o seguinte:
string = ''.join([str(i) for i in list])
l=['a', 1, 'b', 2]
print str(l)[1:-1]
Output: "'a', 1, 'b', 2"
A menos que esteja faltando alguma coisa, ','.join(foo)
deve fazer 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 Pythonico, embora a string resultante seja difícil de analisar se os elementos puderem conter vírgulas - nesse ponto, você precisa de todo o poder do csv
módulo, como Douglas aponta em sua resposta.)
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
eu diria o csv
biblioteca é a única opção sensata aqui, pois foi construída para lidar com todos os casos de uso de csv, como vírgulas em uma string, etc.
Para gerar uma lista l
para 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)
para gerar várias linhas em csv.
Este exemplo é compatível com Python 3, pois a outra resposta aqui usada StringIO
que é Python 2.
só uma coisinha assim :)
String = "Once:Upon:a:Time:A:Long:Time:Ago"
ding = String.split(':')
ring = (" , ").join(ding)
print(ring)
Saída:Uma vez, uma vez, um, tempo, um, longo, tempo, atrás
Meus dois centavos.Eu gosto de um código mais simples 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'
É python, funciona para strings, números, None e string vazia.É curto e atende aos requisitos.Se a lista não contém números, podemos usar esta variação mais simples:
>>> ','.join(ifilter(lambda x: x, l))
Além disso, esta solução não cria uma nova lista, mas usa um iterador, como @Peter Hoffmann apontou (obrigado).