2008-09-04 14 views
288

Quelle serait votre façon préférée de concaténer les chaînes d'une séquence de sorte qu'entre chaque paire consécutive une virgule soit ajoutée. Autrement dit, comment mappez-vous, par exemple, [ 'a', 'b', 'c' ] à 'a,b,c'? (Les cas [ s ] et [] doivent être mis en correspondance avec s et '' respectivement.)Comment feriez-vous une chaîne séparée par des virgules d'une liste?

je finis habituellement utiliser quelque chose comme ''.join(map(lambda x: x+',',l))[:-1], mais aussi un peu insatisfait sentiment.

Editer: Je suis à la fois honteuse et heureuse que la solution soit si simple. Évidemment, je n'ai pas la moindre idée de ce que je fais. (Je probablement besoin concaténation « simple » dans le passé et en quelque sorte appris par cœur s.join([e1,e2,...]) comme raccourci pour s+e1+e2+....)

Répondre

550
myList = ['a','b','c','d'] 
myString = ",".join(myList) 

Cela ne fonctionnera pas si la liste contient des numéros.


Comme Ricardo Reyes suggéré, si elle contient des types non-chaîne (tels que les entiers, flottants, bools, None) puis faire:

myList = ','.join(map(str, myList)) 
+69

vous avez raison, il ne fonctionnera pas si la liste contient des numéros, mais cette façon il:. myList = '' join (carte (str, myList)) –

+0

Ah génial! Je vais utiliser map() dans le futur. J'ai toujours fait: myString = ",". Join ([str (x) pour x dans myList]) –

+6

'myString =", ". Join (myList)' même si la liste contient des nombres. Je l'ai juste essayé. – zengr

55

Pourquoi la carte/lambda magique? Cela ne fonctionne-t-il pas?

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

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

Édition: @ mark-biek indique le cas des nombres. Peut-être la compréhension de la liste:

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

est plus "pythonique".

Éditer2: Merci pour les suggestions. Je vais utiliser le générateur plutôt que la compréhension de la liste à l'avenir.

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

'>>> ','. Join (str (x) pour x dans foo)' est plutôt cool !! – Marslo

+3

Que faire si je veux 'a, b et c'? – Hussain

+0

@Hussain: '", ".join (foo [: - 2] + [" et ".join (foo [-2:])])' ou si vous pouvez obtenir des nombres: '", ".join (itertools .chain ((str (i) pour i dans un [: - 2]), ["et" .join (str (i) pour i dans un [-2:])])) ' –

10

Ne vous voulez juste:

",".join(l) 

Il est évident que cela devient plus compliqué si vous avez besoin de citer/échapper des virgules etc dans les valeurs. Dans ce cas, je vous suggère de regarder le module csv dans la bibliothèque standard:

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

1

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

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

(edit: et comme jmanning2k souligne,

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

est plus sûr et tout à fait Pythonic, bien que la chaîne résultante sera difficile d'analyser si les éléments peuvent contenir des virgules - à ce moment-là, Comme le souligne Douglas dans sa réponse, il faut utiliser toute la puissance du module csv.)

4

@ jmanning2k l'utilisation d'une liste de compréhension 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)) 
+0

Cette solution ne fonctionne pas répondre aux exigences de ne pas ajouter de virgule pour une chaîne vide et d'ajouter un 'None' avec NoneType. – Roberto

8

@Peter Hoffmann

Utilisation d'expressions du générateur a l'avantage de produire aussi un itérateur, mais enregistre itertools importation. De plus, la compréhension des listes est généralement préférable à la cartographie. Par conséquent, je m'attendrais à ce que les expressions génératrices soient préférées à imap.

>>> l = [1, "foo", 4 ,"bar"] 
>>> ",".join(str(bit) for bit in l) 
'1,foo,4,bar' 
3
l=['a', 1, 'b', 2] 

print str(l)[1:-1] 

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

Je pense que vous devriez souligner que contrairement aux autres solutions sur cette page, vous citez aussi des chaînes. – mrdevlar

8

Voici une solution de rechange en Python 3.0 qui permet aux éléments de la liste non-chaîne:

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

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

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

REMARQUE: L'espace après la virgule est intentionnel.

3

pour convertir les numéros contenant la liste procédez comme suit:

string = ''.join([str(i) for i in list]) 
7

",".join(l) ne fonctionnera pas pour 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' 
0

est un exemple ici avec la liste

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

Plus précis: -

>>> 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 
+0

Cette question concernait les listes, pas * les listes de listes *. –

+0

@EeroAaltonen J'ai mis à jour ma réponse, Merci de m'avoir indiqué à droite. –

2
>>> my_list = ['A', '', '', 'D', 'E',] 
>>> ",".join([str(i) for i in my_list if i]) 
'A,D,E' 

my_list peut contenir n'importe quel type de variables. Cela évite le résultat 'A,,,D,E'.

-1

Mes deux cents. J'aime un code plus simple 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' 

Il est pythonique, travaille pour les chaînes, nombres, Aucun et chaîne vide. C'est court et satisfait les exigences. Si la liste ne va pas contenir des chiffres, nous pouvons utiliser cette simple variation:

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

cette solution ne crée pas aussi une nouvelle liste, mais utilise un itérateur, comme @Peter Hoffmann a (merci).

+0

Ceci 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 déprécié. – clearlight

Questions connexes