Jak utworzysz ciąg oddzielony przecinkami z listy ciągów?

526

Jaki byłby Twój preferowany sposób konkatenacji ciągów z sekwencji, tak że między każdą dwiema kolejnymi parami dodaje się przecinek. Oznacza to, w jaki sposób mapa, na przykład, ['a', 'b', 'c']do 'a,b,c'? (Przypadki ['s']i []należy odpowiednio zamapować na 's'i '').

Zwykle używam czegoś podobnego ''.join(map(lambda x: x+',',l))[:-1], ale też czuję się trochę niezadowolony.

Mweerden
źródło

Odpowiedzi:

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

To nie zadziała, jeśli lista zawiera liczby całkowite


A jeśli lista zawiera typy nie łańcuchowe (takie jak liczby całkowite, zmiennoprzecinkowe, boole, Brak), wykonaj:

my_string = ','.join(map(str, my_list)) 
Mark Biek
źródło
Uwaga: jeśli używasz Pythona 2.7 (czego do tej pory nie powinieneś), to użycie str spowoduje wyjątek, jeśli jakikolwiek element na liście ma Unicode.
kroiz
75

Dlaczego map/ lambdamagia? Czy to nie działa?

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

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

W przypadku, gdy na liście znajdują się liczby, możesz skorzystać ze zrozumienia listy:

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

lub wyrażenie generatora:

>>> ','.join(str(x) for x in foo)
jmanning2k
źródło
18

",".join(l)nie będzie działać we wszystkich przypadkach. Sugeruję użycie modułu csv z 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
źródło
Nie ma StringIOw Pythonie 3
Ron Kalian
4
@RonKalian Use from io import StringIOin Python 3
Kevin Ashcraft
13

Oto alternatywne rozwiązanie w Python 3.0, które pozwala na elementy listy nie łańcuchowej:

>>> alist = ['a', 1, (2, 'b')]
  • standardowy sposób

    >>> ", ".join(map(str, alist))
    "a, 1, (2, 'b')"
  • alternatywne rozwiązanie

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

UWAGA: odstęp po przecinku jest zamierzony.

jfs
źródło
11

Nie chcesz po prostu:

",".join(l)

Oczywiście staje się to bardziej skomplikowane, jeśli trzeba podać wartości / przecinki, itp. W takim przypadku proponuję zajrzeć do modułu csv w standardowej bibliotece:

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

Douglas Leeder
źródło
10

@Peter Hoffmann

Korzystanie z wyrażeń generatora ma tę zaletę, że tworzy również iterator, ale oszczędza importowania itertools. Co więcej, rozumienie listy jest zwykle preferowane do mapowania, dlatego spodziewam się, że wyrażenia generatora będą preferowane zamiast imap.

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

my_listmoże zawierać dowolny rodzaj zmiennych. To pozwala uniknąć wyniku 'A,,,D,E'.

Shameem
źródło
4
l=['a', 1, 'b', 2]

print str(l)[1:-1]

Output: "'a', 1, 'b', 2"
AlvaroAV
źródło
1
Myślę, że powinieneś wskazać, że w przeciwieństwie do innych rozwiązań na tej stronie, cytujesz również ciągi znaków.
mrdevlar
3

@ jmanning2k przy użyciu rozumienia listy ma tę wadę, że tworzy nową listę tymczasową. Lepszym rozwiązaniem byłoby użycie itertools.imap, który zwraca iterator

from itertools import imap
l = [1, "foo", 4 ,"bar"]
",".join(imap(str, l))
Peter Hoffmann
źródło
To rozwiązanie nie spełnia wymagań, aby nie dodawać dodatkowego przecinka dla pustego łańcucha i dodawać „Brak” za pomocą NoneType.
Roberto,
sprawdź str.join pracę szybciej listw porównaniu z generatorem
Grijesh Chauhan
3

Oto przykład z listą

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

Bardziej precyzyjne:-

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

Przykład 2: -

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

źródło
1
To pytanie dotyczyło list, a nie list .
Eero Aaltonen
@EeroAaltonen Zaktualizowałem swoją odpowiedź, dziękuję za skierowanie mnie w prawo.
1

Powiedziałbym, że csvbiblioteka jest jedyną sensowną opcją tutaj, ponieważ została zbudowana, aby poradzić sobie ze wszystkimi przypadkami użycia csv, takimi jak przecinki w ciągu itp.

Aby wyświetlić listę ldo pliku .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.  

Możliwe jest również użycie writer.writerows(iterable)do wyprowadzenia wielu wierszy do csv.

Ten przykład jest zgodny z Python 3, ponieważ użyto tu innej odpowiedzi, StringIOktórą jest Python 2.

Ron Kalian
źródło
Ale czy nie jest to zbyt skomplikowane / skomplikowane w porównaniu z innymi odpowiedziami?
Sreenikethan I
0

Chyba że coś mi umknie, ','.join(foo)powinieneś zrobić to, o co prosisz.

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

(edytuj: i jak wskazuje jmanning2k,

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

jest bezpieczniejszy i dość Pythoński, choć wynikowy ciąg znaków będzie trudny do przeanalizowania, jeśli elementy mogą zawierać przecinki - w tym momencie potrzebujesz pełnej mocy csvmodułu, jak podkreśla Douglas w swojej odpowiedzi.)

David Singer
źródło
-2

Moje dwa centy. Lubię prostszy kod jednowierszowy w pythonie:

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

Jest Pythonic, działa na ciągi, liczby, brak i pusty ciąg. Jest krótki i spełnia wymagania. Jeśli lista nie będzie zawierać liczb, możemy użyć tej prostszej odmiany:

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

Również to rozwiązanie nie tworzy nowej listy, ale używa iteratora, takiego jak wskazał @Peter Hoffmann (dzięki).

Roberto
źródło
To jest zbyteczne. Przyjęta odpowiedź jest prosta, bezpośrednia i wyraźnie najlepsze rozwiązanie. Zapewnienie zbyt skomplikowanych alternatyw to bezcelowa strata czasu. Jeśli próbujesz tylko nauczyć się o innych funkcjach języka, gdy istnieją już realne odpowiedzi, robisz to samo, za co mnie zlekceważyłeś.
jasne