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.

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

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)

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'

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.



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' 

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


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

print str(l)[1:-1]

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

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

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

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.


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


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


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.