Преобразование списка в строку, разделенную запятыми, с "и" до последнего элемента - Python 2.7

Я создал эту функцию для анализа списка:

listy = ['item1', 'item2','item3','item4','item5', 'item6']


def coma(abc):
    for i in abc[0:-1]:
        print i+',',
    print "and " + abc[-1] + '.'

coma(listy)

#item1, item2, item3, item4, item5, and item6.

Есть ли более простой способ достичь этого? Это должно быть применимо к спискам любой длины.

Ответ 1

Когда в списке есть 1+ элементов (если нет, просто используйте первый элемент):

>>> "{} and {}".format(", ".join(listy[:-1]),  listy[-1])
'item1, item2, item3, item4, item5, and item6'

Изменить: если вам нужна оксфордская запятая (не знаю, что она даже существовала!) - просто используйте: ", and" isntead.

Ответ 2

def oxford_comma_join(l):
    if not l:
        return ""
    elif len(l) == 1:
        return l[0]
    else:
        return ', '.join(l[:-1]) + ", and " + l[-1]

print(oxford_comma_join(['item1', 'item2', 'item3', 'item4', 'item5', 'item6']))

Вывод:

item1, item2, item3, item4, item5, and item6

Также как в сторону питоновский способ писать

for i in abc[0:-1]:

является

for i in abc[:-1]:

Ответ 3

def coma(lst):
    return '{} and {}'.format(', '.join(lst[:-1]), lst[-1])

Ответ 4

Еще один другой способ:

listy = ['item1', 'item2','item3','item4','item5', 'item6']

первый способ:

print(', '.join('and, ' + listy[item] if item == len(listy)-1 else listy[item]
for item in xrange(len(listy))))

output >>> item1, item2, item3, item4, item5, and, item6

второй способ:

print(', '.join(item for item in listy[:-1]), 'and', listy[-1])

output >>> (item1, item2, item3, item4, item5, 'and', 'item6')

Ответ 5

В python многие функции, работающие со списками, также работают с итераторами (например, join, sum, list). Получить последний элемент итерации не так просто, потому что вы не можете получить длину, потому что она может быть неизвестна заранее.

def coma_iter(iterable):
    sep = ''
    last = None
    for next in iterable:
        if last is not None:
            yield sep
            yield last
            sep = ', '
        last = next
    if sep:
        yield ', and '
    if last is not None:
        yield last

print ''.join(coma_iter(listy))

Ответ 6

Как правило, неверно использовать + при объединении строк, поскольку он обычно медленный. Вместо этого вы можете использовать

def comma(items):
    return "{}, and {}".format(", ".join(items[:-1]), items[-1])

Однако вы должны заметить, что это сломается, если у вас есть только один элемент:

>>> comma(["spam"])
', and spam'

Чтобы решить эту проблему, вы можете либо проверить длину списка (if len(items) >= 2:), либо сделать это, что (imho) немного больше pythonic:

def comma(items):
    start, last = items[:-1], items[-1]

    if start:
        return "{}, and {}".format(", ".join(start), last)
    else:
        return last

Как мы видели выше, один список элементов приведет к пустым значениям для items[:-1]. if last: - это просто pythonic способ проверки, если last пуст.

Ответ 7

Можно также округлить решения с помощью рекурсивного примера.

>>> listy = ['item1', 'item2','item3','item4','item5', 'item6']
>>> def foo(a):
    if len(a) == 1:
        return ', and ' + a[0]
    return a[0] + ', ' + foo(a[1:])

>>> foo(listy)
'item1, item2, item3, item4, item5, , and item6'
>>> 

Ответ 8

Исправление для ответа Крейгса выше для списка из 2 элементов (я не могу комментировать):

def oxford_comma_join(l):
    if not l:
        return ""
    elif len(l) == 1:
        return l[0]
    elif len(l) == 2:
        return l[0] + " and " + l[1]
    else:
        return ', '.join(l[:-1]) + ", and " + l[-1]

print(oxford_comma_join(['item1', 'item2', 'item3', 'item4', 'item5', 'item6']))

print(oxford_comma_join(['i1', 'i2']))

Результаты:

item1, item2, item3, item4, item5, and item6
i1 and i2

Ответ 9

Вы также можете попробовать библиотеку quoter

>>> import quoter
>>> mylist = ['a', 'b', 'c']
>>> quoter.and_join(mylist)
'a, b, and c'
>>> quoter.or_join(mylist)
'a, b, or c'

https://pypi.python.org/pypi/quoter