Как бы вы сделали строку через запятую из списка строк?

529

Какой будет предпочтительный способ объединения строк из последовательности, такой, что между каждыми двумя последовательными парами добавляется запятая. То есть, как вы на карте, например, ['a', 'b', 'c']к 'a,b,c'? (Случаи ['s']и []должны быть сопоставлены 's'и ''соответственно.)

Я обычно заканчиваю тем, что использую что-то подобное ''.join(map(lambda x: x+',',l))[:-1], но также чувствую себя несколько неудовлетворенным.

mweerden
источник

Ответы:

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

Это не будет работать, если список содержит целые числа


И если список содержит не строковые типы (такие как целые числа, числа с плавающей точкой, bools, None), тогда выполните:

my_string = ','.join(map(str, my_list)) 
Марк Бик
источник
Обратите внимание, что если вы используете Python 2.7 (чего вы не должны делать сейчас), тогда использование str вызовет исключение, если какой-либо элемент в списке имеет Unicode.
Кроиз
75

Почему map/ lambdaмагия? Разве это не работает?

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

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

В случае, если в списке есть числа, вы можете использовать понимание списка:

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

или выражение генератора:

>>> ','.join(str(x) for x in foo)
jmanning2k
источник
18

",".join(l)не будет работать для всех случаев. Я бы предложил использовать модуль CSV с 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'
Рики
источник
Нет StringIOв Python 3
Рон Калян
4
@RonKalian Использование from io import StringIOв Python 3
Кевин Ашкрафт
13

Вот альтернативное решение в Python 3.0, которое допускает элементы нестрокового списка:

>>> alist = ['a', 1, (2, 'b')]
  • стандартный способ

    >>> ", ".join(map(str, alist))
    "a, 1, (2, 'b')"
  • альтернативное решение

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

ПРИМЕЧАНИЕ. Пробел после запятой является преднамеренным.

JFS
источник
11

Разве вы просто не хотите:

",".join(l)

Очевидно, что это становится более сложным, если вам нужно заключить в кавычки / экранировать запятые и т. Д. В значениях. В этом случае я бы предложил посмотреть модуль csv в стандартной библиотеке:

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

Дуглас Лидер
источник
10

@ Питер Хоффманн

Преимущество использования выражений генератора также заключается в создании итератора, но экономит импорт itertools. Кроме того, списочные представления обычно предпочтительнее отображения, поэтому я ожидал бы, что генераторные выражения предпочтительнее 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_listможет содержать переменные любого типа. Это позволит избежать результата 'A,,,D,E'.

Шамим
источник
4
l=['a', 1, 'b', 2]

print str(l)[1:-1]

Output: "'a', 1, 'b', 2"
AlvaroAV
источник
1
Я думаю, вы должны указать, что в отличие от других решений на этой странице, вы также цитируете строки.
mrdevlar
3

@ jmanning2k, использующий понимание списка, имеет обратную сторону создания нового временного списка. Лучшим решением было бы использовать itertools.imap, который возвращает итератор

from itertools import imap
l = [1, "foo", 4 ,"bar"]
",".join(imap(str, l))
Питер Хоффманн
источник
Это решение не удовлетворяет требованиям не добавлять лишнюю запятую для пустой строки и добавлять None с NoneType.
Роберто
проверить str.join работу быстрее с listпо сравнению с генератором
Grijesh Chauhan
3

Вот пример со списком

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

Более точным:-

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

Пример 2:

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

источник
1
Этот вопрос был о списках, а не списках списков .
Ээро Аалтонен
@EeroAaltonen Я обновил свой ответ, Спасибо, что указал мне на право.
1

Я бы сказал, что csvбиблиотека - единственная разумная опция, так как она была построена так, чтобы справляться со всеми вариантами использования csv, такими как запятые в строке и т. Д.

Чтобы вывести список lв файл .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.  

Также возможно использовать writer.writerows(iterable)для вывода нескольких строк в CSV.

Этот пример совместим с Python 3, так как здесь используется другой ответ StringIO- Python 2.

Рон Калян
источник
Но не слишком ли много / сложно по сравнению с другими ответами?
Sreenikethan я
0

Если я что-то упустил, ','.join(foo)должен делать то, что вы просите.

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

(редактировать: и, как указывает jmanning2k,

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

является более безопасным и довольно Pythonic, хотя результирующая строка будет трудно разобрать, если элементы могут содержать запятые - в этот момент вам понадобится полная мощность csvмодуля, как указывает Дуглас в своем ответе.)

Дэвид Сингер
источник
-2

Мои два цента. Мне нравится более простой однострочный код в 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, работает для строк, чисел, None и пустой строки. Это коротко и удовлетворяет требованиям. Если список не будет содержать чисел, мы можем использовать этот более простой вариант:

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

Также это решение не создает новый список, но использует итератор, как указал @Peter Hoffmann (спасибо).

Роберто
источник
Это лишнее. Принятый ответ является простым, прямым и явно лучшим решением. Предоставлять слишком сложные альтернативы - бессмысленная трата времени. Если вы просто пытаетесь рассказать о других особенностях языка, когда уже есть жизнеспособные ответы, вы делаете то же самое, за что вы меня опровергли.
ясный свет