Skip to content
Advertisement

Automate the boring stuff with Python: Comma Code

Currently working my way through this beginners book and have completed one of the practice projects ‘Comma Code’ which asks the user to construct a program which:

takes a list value as an argument and returns a string with all the items separated by a comma and a space, with and inserted before the last item. For example, passing the below spam list to the function would return ‘apples, bananas, tofu, and cats’. But your function should be able to work with any list value passed to it.

spam = ['apples', 'bananas', 'tofu', 'cats']

My solution to the problem (Which works perfectly fine):

spam= ['apples', 'bananas', 'tofu', 'cats']
def list_thing(list):
    new_string = ''
    for i in list:
        new_string = new_string + str(i)
        if list.index(i) == (len(list)-2):
            new_string = new_string + ', and '
        elif list.index(i) == (len(list)-1):
            new_string = new_string
        else:
            new_string = new_string + ', '
    return new_string

print (list_thing(spam))

My only question, is there any way I can shorten my code? or make it more ‘pythonic’?

Here is my code.

def listTostring(someList):
    a = ''
    for i in range(len(someList)-1):
        a += str(someList[i])
    a += str('and ' + someList[len(someList)-1])
    print (a)

spam = ['apples', 'bananas', 'tofu', 'cats']
listTostring(spam)

output: apples, bananas, tofu, and cats

Advertisement

Answer

Use str.join() to join a sequence of strings with a delimiter. If you do so for all words except for the last, you can insert ' and ' there instead:

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

Breaking this down:

  • words[-1] takes the last element of a list. words[:-1] slices the list to produce a new list with all words except the last one.

  • ', '.join() produces a new string, with all strings of the argument to str.join() joined with ', '. If there is just one element in the input list, that one element is returned, unjoined.

  • '{}, and {}'.format() inserts the comma-joined words and the last word into a template (complete with Oxford comma).

If you pass in an empty list, the above function will raise an IndexError exception; you could specifically test for that case in the function if you feel an empty list is a valid use-case for the function.

So the above joins all words except the last with ', ', then adds the last word to the result with ' and '.

Note that if there is just one word, you get that one word; there is nothing to join in that case. If there are two, you get 'word1 and word 2'. More words produces 'word1, word2, ... and lastword'.

Demo:

>>> def list_thing(words):
...     if len(words) == 1:
...         return words[0]
...     return '{}, and {}'.format(', '.join(words[:-1]), words[-1])
...
>>> spam = ['apples', 'bananas', 'tofu', 'cats']
>>> list_thing(spam[:1])
'apples'
>>> list_thing(spam[:2])
'apples, and bananas'
>>> list_thing(spam[:3])
'apples, bananas, and tofu'
>>> list_thing(spam)
'apples, bananas, tofu, and cats'
Advertisement