What's the most pythonic way of joining a list so that there are commas between each item, except for the last which uses "and"?
["foo"] --> "foo"
["foo","bar"] --> "foo and bar"
["foo","bar","baz"] --> "foo, bar and baz"
["foo","bar","baz","bah"] --> "foo, bar, baz and bah"
This expression does it:
print ", ".join(data[:-2] + [" and ".join(data[-2:])])
As seen here:
>>> 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
Try this, it takes into consideration the edge cases and uses format()
, to show another possible solution:
def my_join(lst): if not lst: return "" elif len(lst) == 1: return str(lst[0]) return "{} and {}".format(", ".join(lst[:-1]), lst[-1])
Works as expected:
my_join([]) => "" my_join(["x"]) => "x" my_join(["x", "y"]) => "x and y" my_join(["x", "y", "z"]) => "x, y and z"
The fix based on the comment led to this fun way. It assumes no commas occur in the string entries of the list to be joined (which would be problematic anyway, so is a reasonable assumption.)
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'
Already good answers available. This one works in all test cases and is slightly different than some others.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With