Python: грамматически корректная читаемая человеком строка из списка (с оксфордской запятой)

Я хочу, чтобы грамматически правильное читаемое человеком строковое представление списка. Например, список ['A', 2, None, 'B,B', 'C,C,C'] должен вернуть строку A, 2, None, B,B, and C,C,C, Этот надуманный пример несколько необходим. Обратите внимание, что оксфордская запятая имеет отношение к этому вопросу.

Я старался ', '.join(seq) но это не дает ожидаемого результата для вышеупомянутого примера.

Обратите внимание на ранее существовавшие подобные вопросы:

2 ответа

Эта функция работает. Маленькие списки обрабатываются по-разному.

from typing import Any, List

def readable_list(seq: List[Any]) -> str:
    seq = [str(s) for s in seq]
    if len(seq) < 3:
        return ' and '.join(seq)
    return ', '.join(seq[:-1]) + ', and ' + seq[-1]

Примеры использования:

readable_list([])
''

readable_list(['A'])
'A'

readable_list(['A', 2])
'A and 2'

readable_list(['A', None, 'C'])
'A, None, and C'

readable_list(['A', 'B,B', 'C,C,C'])
'A, B,B, and C,C,C'

readable_list(['A', 'B', 'C', 'D'])
'A, B, C, and D'

Вы также можете использовать распаковку для более чистого решения:

def readable_list(_s):
  if len(_s) < 3:
    return ' and '.join(map(str, _s))
  *a, b = _s
  return f"{', '.join(map(str, a))}, and {b}"

vals = [[], ['A'], ['A', 2], ['A', None, 'C'], ['A', 'B,B', 'C,C,C'], ['A', 'B', 'C', 'D']]
print([readable_list(i) for i in vals])

Выход:

['', 'A', 'A and 2', 'A, None, and C', 'A, B,B, and C,C,C', 'A, B, C, and D']

Я стал очень упрямым и очень хотел придумать однострочное решение.

"{} and {}".format(seq[0], seq[1]) if len(seq)==2 else ', '.join([str(x) if (y < len(seq)-1 or len(seq)<=1) else "and {}".format(str(x)) for x, y in zip(seq, range(len(seq)))])

ИЗМЕНИТЬ
Я думаю, что это трюк. И я думаю, что проблема еще сложнее, чем я думал, чтобы ее решить с помощью некрасивого однострочника.

Основываясь на принятом ответе для темы, с которой вы связались, вот однострочный текст, который принимает необязательный аргумент о том, использовать ли оксфордскую запятую или нет.

from typing import List

def list_items_in_english(l: List[str], oxford_comma: bool = True) -> str:
    """
    Produce a list of the items formatted as they would be in an English sentence.
    So one item returns just the item, passing two items returns "item1 and item2" and
    three returns "item1, item2, and item3" with an optional Oxford comma.
    """
    return ", ".join(l[:-2] + [((oxford_comma and len(l) != 2) * ',' + " and ").join(l[-2:])])
Другие вопросы по тегам