Comment feriez-vous une chaîne séparée par des virgules à partir d'une liste de chaînes?


529

Quelle serait votre façon préférée de concaténer des chaînes d'une séquence de telle sorte qu'entre deux paires consécutives, une virgule soit ajoutée. Autrement dit, comment mappez-vous, par exemple, ['a', 'b', 'c']à 'a,b,c'? (Les cas ['s']et []doivent être mappés respectivement à 's'et ''.)

Je finis généralement par utiliser quelque chose comme ''.join(map(lambda x: x+',',l))[:-1], mais je me sens aussi quelque peu insatisfait.

Réponses:


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

Cela ne fonctionnera pas si la liste contient des entiers


Et si la liste contient des types autres que des chaînes (tels que des entiers, des flottants, des booléens, Aucun), procédez comme suit:

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

Notez que si vous utilisez python 2.7 (ce que vous ne devriez pas faire maintenant), l'utilisation de str lèvera une exception si l'un des éléments de la liste a unicode.
kroiz

75

Pourquoi la map/ lambdamagie? Ça ne marche pas?

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

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

Si la liste contient des nombres, vous pouvez utiliser la compréhension de la liste:

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

ou une expression de générateur:

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

18

",".join(l)ne fonctionnera pas dans tous les cas. Je suggère d'utiliser le module csv avec 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'

Il n'y StringIOen a pas dans Python 3
Ron Kalian

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

13

Voici une solution alternative en Python 3.0 qui permet des éléments de liste non-chaîne:

>>> alist = ['a', 1, (2, 'b')]
  • une manière standard

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

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

REMARQUE: l'espace après une virgule est intentionnel.



10

@Peter Hoffmann

L'utilisation d'expressions de générateur a également l'avantage de produire un itérateur, mais économise l'importation d'itertools. De plus, les compréhensions de liste sont généralement préférées à mapper, donc je m'attends à ce que les expressions de générateur soient préférées à 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_listpeut contenir tout type de variables. Cela évite le résultat 'A,,,D,E'.


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

print str(l)[1:-1]

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

1
Je pense que vous devez souligner que contrairement aux autres solutions de cette page, vous citez également des chaînes.
mrdevlar

3

@ jmanning2k utilisant une compréhension de liste a l'inconvénient de créer une nouvelle liste temporaire. La meilleure solution serait d'utiliser itertools.imap qui retourne un itérateur

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

Cette solution ne remplit pas les conditions de ne pas ajouter de virgule supplémentaire pour une chaîne vide et d'ajouter un «Aucun» avec NoneType.
Roberto

vérifier le str.join travail plus rapidement par listrapport au générateur
Grijesh Chauhan

3

Voici un exemple avec liste

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

Plus précise:-

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

Exemple 2: -

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

1
Cette question concernait les listes, pas les listes de listes .
Eero Aaltonen

@EeroAaltonen J'ai mis à jour ma réponse, merci de me pointer vers la droite.

1

Je dirais csv bibliothèque est la seule option raisonnable ici, car elle a été conçue pour faire face à tous les cas d'utilisation csv tels que les virgules dans une chaîne, etc.

Pour sortir une liste ldans un fichier .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.  

Il est également possible d'utiliser writer.writerows(iterable) pour sortir plusieurs lignes vers csv.

Cet exemple est compatible avec Python 3, car l'autre réponse utilisée ici StringIOest Python 2.


Mais n'est-ce pas trop / compliqué par rapport aux autres réponses?
Sreenikethan I

0

À moins que je manque quelque chose, ','.join(foo)je dois faire ce que vous demandez.

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

(modifier: et comme le souligne jmanning2k,

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

est plus sûr et assez Pythonique, bien que la chaîne résultante soit difficile à analyser si les éléments peuvent contenir des virgules - à ce stade, vous avez besoin de la pleine puissance du csvmodule, comme Douglas le souligne dans sa réponse.)


-2

Mes deux centimes. J'aime plus simple un code d'une ligne 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'

C'est pythonique, fonctionne pour les chaînes, les nombres, Aucun et la chaîne vide. Il est court et répond aux exigences. Si la liste ne contient pas de nombres, nous pouvons utiliser cette variante plus simple:

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

De plus, cette solution ne crée pas de nouvelle liste, mais utilise un itérateur, comme l'a souligné @Peter Hoffmann (merci).


C'est superflu. La réponse acceptée est simple, directe et clairement la meilleure solution. Fournir des alternatives trop complexes est une perte de temps inutile. Si vous essayez simplement d'éduquer sur d'autres caractéristiques de la langue alors qu'il existe déjà des réponses viables, vous faites la même chose pour laquelle vous m'avez rétrogradé.
clearlight
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.