Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automate the boring stuff with Python: Comma Code

Tags:

python

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

like image 865
Sutharsan Sethurayar Avatar asked Nov 27 '22 03:11

Sutharsan Sethurayar


2 Answers

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'
like image 125
Martijn Pieters Avatar answered Dec 10 '22 16:12

Martijn Pieters


I used a different approach. I am a beginner, so I don't know if it's the cleanest way to do it. To me it seemed as the most simple way:

spam = ['apples', 'pizza', 'dogs', 'cats']

def comma(items):
    for i in range(len(items) -2):
        print(items[i], end=", ")# minor adjustment from one beginner to another: to make it cleaner, simply move the ', ' to equal 'end'. the print statement should finish like this --> end=', '
    print(items[-2] + 'and ' + items[-1]) 

comma(spam)

Which will give the output:

apples, pizza, dogs and cats
like image 31
Hein de Wilde Avatar answered Dec 10 '22 16:12

Hein de Wilde