Come faresti una stringa separata da virgole da un elenco di stringhe?


529

Quale sarebbe il tuo modo preferito per concatenare le stringhe da una sequenza in modo tale che ogni due coppie consecutive venga aggiunta una virgola. Cioè, come si mappa, ad esempio, ['a', 'b', 'c']a 'a,b,c'? (I casi ['s']e []devono essere mappati su 's'e '', rispettivamente.)

Di solito finisco per usare qualcosa del genere ''.join(map(lambda x: x+',',l))[:-1], ma mi sento anche un po 'insoddisfatto.

Risposte:


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

Questo non funzionerà se l'elenco contiene numeri interi


E se l'elenco contiene tipi non stringa (come numeri interi, float, bool, Nessuno), allora fai:

my_string = ','.join(map(str, my_list)) 

Nota se stai usando Python 2.7 (cosa che non dovresti fare ora), l'uso di str solleverà un'eccezione se uno qualsiasi degli elementi nella lista ha unicode.
kroiz,

75

Perché la map/ lambdamagia? Non funziona?

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

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

Nel caso in cui ci siano numeri nell'elenco, è possibile utilizzare la comprensione dell'elenco:

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

o un'espressione del generatore:

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

18

",".join(l)non funzionerà per tutti i casi. Suggerirei di usare il modulo CSV con 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'

Non c'è StringIOin Python 3
Ron Kalian il

4
@RonKalian Use from io import StringIOin Python 3
Kevin Ashcraft,

13

Ecco una soluzione alternativa in Python 3.0 che consente voci di elenco senza stringhe:

>>> alist = ['a', 1, (2, 'b')]
  • un modo standard

    >>> ", ".join(map(str, alist))
    "a, 1, (2, 'b')"
  • la soluzione alternativa

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

NOTA: lo spazio dopo la virgola è intenzionale.



10

@Peter Hoffmann

L'uso delle espressioni del generatore ha anche il vantaggio di produrre un iteratore ma salva l'importazione di itertools. Inoltre, si preferisce generalmente mappare le comprensioni degli elenchi, quindi mi aspetto che le espressioni del generatore vengano preferite da 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_listpuò contenere qualsiasi tipo di variabile. Questo evita il risultato 'A,,,D,E'.


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

print str(l)[1:-1]

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

1
Penso che dovresti sottolineare che, diversamente dalle altre soluzioni in questa pagina, citi anche le stringhe.
mrdevlar,

3

@ jmanning2k utilizzando una comprensione dell'elenco ha il rovescio della medaglia della creazione di un nuovo elenco temporaneo. La soluzione migliore sarebbe usare itertools.imap che restituisce un iteratore

from itertools import imap
l = [1, "foo", 4 ,"bar"]
",".join(imap(str, l))

Questa soluzione non soddisfa i requisiti di non aggiungere una virgola aggiuntiva per stringa vuota e di aggiungere un 'Nessuno' con NoneType.
Roberto

controllare il str.join lavoro più veloce listrispetto al generatore
Grijesh Chauhan

3

Ecco un esempio con la lista

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

Più accurato:-

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

Esempio 2: -

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

1
Questa domanda riguardava gli elenchi, non gli elenchi di elenchi .
Eero Aaltonen,

@EeroAaltonen Ho aggiornato la mia risposta, grazie per avermi indicato a destra.

1

Direi che la csvlibreria è l'unica opzione sensata qui, poiché è stata costruita per far fronte a tutti i casi d'uso CSV come virgole in una stringa, ecc.

Per generare un elenco lin un file .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.  

È anche possibile utilizzare writer.writerows(iterable)per generare più righe su CSV.

Questo esempio è compatibile con Python 3, come l'altra risposta usata qui StringIOè Python 2.


Ma non è troppo / complicato rispetto ad altre risposte?
Sreenikethan I

0

A meno che non mi manchi qualcosa, ','.join(foo)dovrebbe fare quello che stai chiedendo.

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

(modifica: e come sottolinea jmanning2k,

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

è più sicuro e abbastanza Pythonic, sebbene la stringa risultante sarà difficile da analizzare se gli elementi possono contenere virgole - a quel punto, hai bisogno della piena potenza del csvmodulo, come Douglas sottolinea nella sua risposta.)


-2

I miei due centesimi. Mi piace un codice di una riga più semplice in 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, funziona con stringhe, numeri, None e stringhe vuote. È corto e soddisfa i requisiti. Se l'elenco non contiene numeri, possiamo usare questa variazione più semplice:

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

Anche questa soluzione non crea un nuovo elenco, ma utilizza un iteratore, come ha sottolineato @Peter Hoffmann (grazie).


Questo è superfluo. La risposta accettata è semplice, diretta e chiaramente la migliore soluzione. Fornire alternative troppo complesse è inutile perdere tempo. Se stai semplicemente cercando di educare su altre caratteristiche della lingua quando ci sono già risposte valide, stai facendo la stessa cosa per cui mi hai votato.
chiarimento il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.