Объединяя слова вместе с запятой, и "и"

Я работаю через Автоматизировать скучный материал с помощью Python. Я не могу понять, как удалить конечную выходную запятую из приведенной ниже программы. Цель состоит в том, чтобы побуждать пользователя вводить значения, которые затем распечатываются в списке, с "и", вставленными до конца. Результат должен выглядеть примерно так:

apples, bananas, tofu, and cats

Моя выглядит следующим образом:

apples, bananas, tofu, and cats,

Эта последняя запятая меня заводит NUTS.

def lister():
    listed = []
    while True:
        print('type what you want to be listed or type nothing to exit')
        inputted = input()
        if inputted == '':
            break
        else:
            listed.append(inputted+',')
    listed.insert(-1, 'and')
    for i in listed:
        print(i, end=' ')
lister()

Ответы

Ответ 1

Вы можете избежать добавления запятых в каждую строку в списке, отложив форматирование на время печати. Присоедините все элементы, исключая последнее из ', ', затем используйте форматирование, чтобы вставить объединенную строку с последним элементом, соединенным с помощью and:

listed.append(inputed)
...
print('{}, and {}'.format(', '.join(listed[:-1]), listed[-1]))

Демо:

>>> listed = ['a', 'b', 'c', 'd']
>>> print('{}, and {}'.format(', '.join(listed[:-1]), listed[-1]))
a, b, c, and d

Ответ 2

Принятый ответ хорош, но может быть лучше переместить эту функциональность в отдельную функцию, которая принимает список, а также обрабатывать крайние случаи из 0, 1 или 2 элементов в списке:

def oxfordcomma(listed):
    if len(listed) == 0:
        return ''
    if len(listed) == 1:
        return listed[0]
    if len(listed) == 2:
        return listed[0] + ' and ' + listed[1]
    return ', '.join(listed[:-1]) + ', and ' + listed[-1]

Тестовые случаи:

>>> oxfordcomma([])
''
>>> oxfordcomma(['apples'])
'apples'
>>> oxfordcomma(['apples', 'pears'])
'apples and pears'
>>> oxfordcomma(['apples', 'pears', 'grapes'])
'apples, pears, and grapes'

Ответ 3

Это приведет к удалению запятой из последнего слова.

listed[-1] = listed[-1][:-1]

Как это работает, listed[-1] получает последнее значение из списка. Мы используем =, чтобы присвоить этому значению значение listed[-1][:-1], которое представляет собой фрагмент последнего слова из списка со всем, что было до последнего символа.

Реализовано, как показано ниже:

def lister():
    listed = []
    while True:
        print('type what you want to be listed or type nothing to exit')
        inputted = input()
        if inputted == '':
            break
        else:
            listed.append(inputted+',')
    listed.insert(-1, 'and')
    listed[-1] = listed[-1][:-1]
    for i in listed:
        print(i, end=' ')
lister()

Ответ 4

Немного измените свой код...

def lister():
    listed = []
    while True:
        print('type what you want to be listed or type nothing to exit')
        inputted = input()
        if inputted == '':
            break
        else:
            listed.append(inputted) # removed the comma here

    print(', '.join(listed[:-2]) + ' and ' + listed[-1])  #using the join operator, and appending and xxx at the end
lister()

Ответ 5

listed[-1] = listed[-1][:-1]

Это усечет окончательный символ последней строки в listed.

Ответ 6

Много способов сделать это, но как насчет этого?

# listed[-1] is the last element of the list
# rstrip removes matching characters from the end of the string
listed[-1] = listed[-1].rstrip(',')
listed.insert(-1, 'and')
for i in listed:
    print(i, end=' ')

Вы все равно будете печатать пробел в конце строки, но я думаю, вы его не увидите и, следовательно, все равно.: -)

Ответ 7

Чтобы быть полностью правильным и красивым, я бы сделал это, используя f-строку (форматированный строковый литерал, Python 3. 6+). И я бы выбросил оксфордскую запятую, чтобы вам не пришлось добавлять дополнительный крайний регистр для len(word) == 2:

def grammatically_join(words):
    if len(words) == 0:
        return ""
    if len(words) == 1:
        return listed[0]
    return f'{", ".join(words[:-1])} and {words[-1]}'

Вы также можете сделать это одной строкой:

", and ".join(", ".join(words).rsplit(", ", 1))

Но это не читается. Сначала ", ".join(words) весь список, затем разбивает результирующую строку на последнее вхождение ", " и соединяет список из двух элементов с " and ". Если последняя строка в вашем списке может содержать запятую, за которой следует пробел, этот код будет разбит. Но он будет обрабатывать случай, когда в listed есть только один или несколько элементов, в отличие от текущего верхнего ответа.