How to effectively combine a list with commas and add "and" to the last item

I went through the Automatetheboringstuff and came across a call called Comma Code (end of chapter 4 ). You must write a function that takes a list and prints a string, connecting the elements with a comma and adding "and" to the last element.

Remembering that I'm pretty new to python or programming in this regard, it was still a manageable task, but there was a comma in front of the inserted "and". So I revised the code to clear it. This is my code:

def comma_separator(someList): """The function comma_separator takes a list and joins it into a string with (", ") and adds " and " before the last value.""" if type(someList) is list and bool(someList) is True: return ", ".join(someList[:-1]) + " and " + someList[-1] else: print("Pass a non-empty list as the argument.") 

Is there a better way to do this? Is there a module that can do this?

+4
source share
3 answers

You will need to consider the case when you have only one element:

 def comma_separator(sequence): if not sequence: return '' if len(sequence) == 1: return sequence[0] return '{} and {}'.format(', '.join(sequence[:-1]), sequence[-1]) 

Note that bool(sequence) is True is a very complex test method for a non-empty list; just using if sequence: enough, because the if already looking for a logical truth.

Perhaps calling a function with anything but a sequence (something that can be indexed and has a length) should just throw an exception. Usually you do not check types in such functions. If you need to check the type, use isinstance(sequence, list) to at least allow subclasses.

I would also make a mistake to go to the empty list. You can turn this exception into a ValueError :

 def comma_separator(sequence): if len(sequence) > 1: return '{} and {}'.format(', '.join(sequence[:-1]), sequence[-1]) try: return sequence[0] except IndexError: raise ValueError('Must pass in at least one element') 

Demonstration of the latter:

 >>> def comma_separator(sequence): ... if len(sequence) > 1: ... return '{} and {}'.format(', '.join(sequence[:-1]), sequence[-1]) ... try: ... return sequence[0] ... except IndexError: ... raise ValueError('Must pass in at least one element') ... >>> comma_separator(['foo', 'bar', 'baz']) 'foo, bar and baz' >>> comma_separator(['foo', 'bar']) 'foo and bar' >>> comma_separator(['foo']) 'foo' >>> comma_separator([]) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 7, in comma_separator ValueError: Must pass in at least one element 
+12
source

As an alternative to Martijn's readable answer, you can use two str.join() ; an inner join that connects to commas except for the last element in a given sequence, and an outer join that connects to and result of an inner join to the last element. This is single line:

 def comma_separator(seq): return ' and '.join([', '.join(seq[:-1]), seq[-1]] if len(seq) > 2 else seq) >>> comma_separator([]) '' >>> comma_separator(['a']) 'a' >>> comma_separator(['a', 'b']) 'a and b' >>> comma_separator(['a', 'b', 'c']) 'a, b and c' >>> comma_separator(['a', 'b', 'c', 'd']) 'a, b, c and d' 

This does not treat the empty sequence as an error, but instead returns an empty string.

+4
source
 ', '.join(elements[:-1]) + ' and ' + elements[-1] 
-3
source

All Articles