¿Cómo haría una cadena separada por comas de una lista de cadenas?

529

¿Cuál sería su forma preferida de concatenar cadenas de una secuencia de manera que entre cada dos pares consecutivos se agregue una coma? Es decir, ¿cómo se asigna, por ejemplo, ['a', 'b', 'c']a 'a,b,c'? (Los casos ['s']y []deben asignarse a 's'y '', respectivamente.)

Por lo general, termino usando algo como ''.join(map(lambda x: x+',',l))[:-1], pero también me siento algo insatisfecho.

mweerden
fuente

Respuestas:

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

Esto no funcionará si la lista contiene enteros


Y si la lista contiene tipos que no son de cadena (como enteros, flotantes, bools, Ninguno), haga lo siguiente:

my_string = ','.join(map(str, my_list)) 
Mark Biek
fuente
Tenga en cuenta que si está utilizando Python 2.7 (que no debería tener ahora), el uso de str generará una excepción si algún elemento de la lista tiene unicode.
kroiz
75

¿Por qué la map/ lambdamagia? ¿Esto no funciona?

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

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

En caso de que haya números en la lista, puede usar la comprensión de la lista:

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

o una expresión generadora:

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

",".join(l)no funcionará para todos los casos. Sugeriría usar el módulo 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'
Ricky
fuente
No hay StringIOen Python 3
Ron Kalian
44
Uso de @RonKalian from io import StringIOen Python 3
Kevin Ashcraft
13

Aquí hay una solución alternativa en Python 3.0 que permite elementos de lista sin cadenas:

>>> alist = ['a', 1, (2, 'b')]
  • una forma estándar

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

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

NOTA: El espacio después de la coma es intencional.

jfs
fuente
11

No solo quieres:

",".join(l)

Obviamente, se vuelve más complicado si necesita citar / escapar comas, etc. en los valores. En ese caso, sugeriría mirar el módulo csv en la biblioteca estándar:

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

Douglas Leeder
fuente
10

@Peter Hoffmann

El uso de expresiones generadoras tiene el beneficio de producir también un iterador pero ahorra la importación de herramientas iterativas. Además, las comprensiones de listas generalmente se prefieren al mapeo, por lo tanto, esperaría que las expresiones generadoras sean preferidas a imap.

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

my_listpuede contener cualquier tipo de variables. Esto evita el resultado 'A,,,D,E'.

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

print str(l)[1:-1]

Output: "'a', 1, 'b', 2"
AlvaroAV
fuente
1
Creo que debería señalar que, a diferencia de las otras soluciones en esta página, también cita cadenas.
mrdevlar
3

@ jmanning2k usando una lista de comprensión tiene la desventaja de crear una nueva lista temporal. La mejor solución sería usar itertools.imap que devuelve un iterador

from itertools import imap
l = [1, "foo", 4 ,"bar"]
",".join(imap(str, l))
Peter Hoffmann
fuente
Esta solución no cumple los requisitos de no agregar una coma adicional para una cadena vacía y agregar un 'Ninguno' con NoneType.
Roberto
verifique el str.join trabajo más rápido listen comparación con el generador
Grijesh Chauhan
3

Aquí hay un ejemplo con la lista

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

Más preciso:-

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

Ejemplo 2: -

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

fuente
1
Esta pregunta era sobre listas, no listas de listas .
Eero Aaltonen
@EeroAaltonen Actualicé Mi respuesta, Gracias por señalarme a la derecha.
1

Diría que la csvbiblioteca es la única opción sensata aquí, ya que se creó para hacer frente a todos los casos de uso de csv, como comas en una cadena, etc.

Para enviar una lista la un archivo .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.  

También es posible usar writer.writerows(iterable)para generar múltiples filas en csv.

Este ejemplo es compatible con Python 3, ya que la otra respuesta aquí utilizada StringIOes Python 2.

Ron Kalian
fuente
Pero, ¿no es eso demasiado complicado en comparación con otras respuestas?
Sreenikethan I
0

A menos que me falte algo, ','.join(foo)debería hacer lo que me pides.

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

(editar: y como señala jmanning2k,

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

es más seguro y bastante pitónico, aunque la cadena resultante será difícil de analizar si los elementos pueden contener comas; en ese punto, necesita toda la potencia del csvmódulo, como Douglas señala en su respuesta).

David Singer
fuente
-2

Mis dos centavos. Me gusta más simple un código de una línea en 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'

Es pitónico, funciona para cadenas, números, Ninguno y cadena vacía. Es corto y cumple los requisitos. Si la lista no va a contener números, podemos usar esta variación más simple:

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

Además, esta solución no crea una nueva lista, sino que usa un iterador, como señaló @Peter Hoffmann (gracias).

Roberto
fuente
Esto es superfluo. La respuesta aceptada es simple, directa y claramente la mejor solución. Brindar alternativas demasiado complejas es una pérdida de tiempo inútil. Si simplemente está tratando de educar sobre otras características del lenguaje cuando ya hay respuestas viables, está haciendo lo mismo por lo que me rechazó.
clearlight