Грамматический список Присоединиться к Python
Какой самый питонический способ объединения списка, чтобы между каждым элементом были запятые, кроме последнего, который использует "и"?
["foo"] --> "foo"
["foo","bar"] --> "foo and bar"
["foo","bar","baz"] --> "foo, bar and baz"
["foo","bar","baz","bah"] --> "foo, bar, baz and bah"
Ответы
Ответ 1
Это выражение делает это:
print ", ".join(data[:-2] + [" and ".join(data[-2:])])
Как показано здесь:
>>> data
['foo', 'bar', 'baaz', 'bah']
>>> while data:
... print ", ".join(data[:-2] + [" and ".join(data[-2:])])
... data.pop()
...
foo, bar, baaz and bah
foo, bar and baaz
foo and bar
foo
Ответ 2
Попробуйте это, он принимает во внимание случаи краев и использует format()
, чтобы показать другое возможное решение:
def my_join(lst):
if not lst:
return ""
elif len(lst) == 1:
return str(lst[0])
return "{} and {}".format(", ".join(lst[:-1]), lst[-1])
Работает как ожидалось:
my_join([])
=> ""
my_join(["x"])
=> "x"
my_join(["x", "y"])
=> "x and y"
my_join(["x", "y", "z"])
=> "x, y and z"
Ответ 3
Исправление, основанное на комментарии, привело к этому интересному способу. Он предполагает, что никакие запятые не встречаются в строковых записях списка, который должен быть соединен (что было бы проблематично, так что это разумное предположение.)
def special_join(my_list):
return ", ".join(my_list)[::-1].replace(",", "dna ", 1)[::-1]
In [50]: def special_join(my_list):
return ", ".join(my_list)[::-1].replace(",", "dna ", 1)[::-1]
....:
In [51]: special_join(["foo", "bar", "baz", "bah"])
Out[51]: 'foo, bar, baz and bah'
In [52]: special_join(["foo"])
Out[52]: 'foo'
In [53]: special_join(["foo", "bar"])
Out[53]: 'foo and bar'
Ответ 4
Уже есть хорошие ответы. Это работает во всех тестовых случаях и немного отличается от некоторых других.
def grammar_join(words):
return reduce(lambda x, y: x and x + ' and ' + y or y,
(', '.join(words[:-1]), words[-1])) if words else ''
tests = ([], ['a'], ['a', 'b'], ['a', 'b', 'c'])
for test in tests:
print grammar_join(test)
a
a and b
a, b and c
Ответ 5
только специальный случай последний. что-то вроде этого:
'%s and %s'%(', '.join(mylist[:-1]),mylist[-1])
вероятно, не будет более сжатого метода.
это тоже не будет выполнено в нулевом случае.
Ответ 6
Если вам нужно решение, в котором отрицательная индексация не поддерживается (например, Django QuerySet)
def oxford_join(string_list):
if len(string_list) < 1:
text = ''
elif len(string_list) == 1:
text = string_list[0]
elif len(string_list) == 2:
text = ' and '.join(string_list)
else:
text = ', '.join(string_list)
text = '{parts[0]}, and {parts[2]}'.format(parts=text.rpartition(', ')) # oxford comma
return text
oxford_join(['Apples', 'Oranges', 'Mangoes'])