Comma Code - Ch. 4 Automate the Boring Stuff I am new to programming and currently learning Python using &quot;Automate the Boring&quot; by Al Sweigart. I've just completed the &quot;Comma Code&quot; task in Chapter 4 and would like some feedback on my solution. The task is:

Say you have a list value like this:
spam = ['apples', 'bananas', 'tofu', 'cats']

Write a function that takes a list value as an argument and returns a string with all the items separated by a comma and space, with and inserted before the last item. For example, passing the previous 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.

I tried to come up with something that mostly sticks to what you learn by this point in the book, but I did use .join() which is from a few chapters later. I also tried to make sure my code works with lists containing strings and/or integers, and for the output to be correct independent of list size (no comma when the list has two items, etc.).
your_list = ['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]

def list_concatenator(your_list):
    items = len(your_list)
    if items == 0:
        return 'Your list is empty'

    elif items == 1:
        return &quot;'&quot; + str(your_list[0]) + &quot;'&quot;

    elif items == 2:
        return &quot;'&quot; + str(your_list[0]) + ' and ' + str(your_list[1]) + &quot;'&quot;

    else:      
        your_list_split1 = (', '.join((map(str,your_list[:-1]))))
        return &quot;'&quot; + your_list_split1 + ', and ' + str(your_list[-1]) + &quot;'&quot;

list_concatenator(your_list)

I realize these exercises have been answered before, I'm just looking for some feedback on my solution.
Your code is well-built and covers everything stated in the task, but could be made much shorter by using the .format() function. 


  str.format() is one of the string formatting methods in Python 3, which
  allows multiple substitutions and value formatting. This method lets
  us concatenate elements within a string through positional formatting.


Your code can, therefore, be made shorter and more concise this way. Here is what your code might look like - 

def list_concatenator(your_list):

     if not your_list:
         return "Your list is empty!"

     elif len(your_list) == 1:
         return str(your_list[0])

     elif len(your_list) == 2:
         return '{0} and {1}'.format(your_list[0], your_list[1])

     else:
         body = ", ".join(map(str, your_list[:-1]))
         return '{0}, and {1}'.format(body, your_list[-1])


I have used {0} and {1} so that positional arguments can be placed in the order you want them to be in, though it is not necessary to do so.

OR

Another way to format in Python 3 is to use f-strings.


  The idea behind f-strings is to make string interpolation simpler. To create an f-string, prefix the string with the letter “ f ”. The string itself can be formatted in much the same way that you would with str.format(). f-strings provide a concise and convenient way to embed python expressions inside string literals for formatting.


Here's how your code would look like with f-strings (much shorter) - 

def list_concetenator(your_list):

    if not your_list:
        return "Your list is empty!"

    elif len(your_list) == 1:
        return str(your_list[0])

    elif len(your_list) == 2:
        return f'{your_list[0]} and {your_list[1]}'

    else:
        body = ", ".join(map(str, a_list[:-1]))
        return f'{body}, and {your_list[-1]}'


Here are some example outputs -

your_list = ['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]

print(list_concatenator(['item1', 'item2', 3, 'item4', 'item5', 'item6', 7, 'item8', 9]))
&gt;&gt;&gt; item1, item2, 3, item4, item5, item6, 7, item8, and 9

print(list_concatenator(['item1', 'item2', 3]))
&gt;&gt;&gt; item1, item2, and 3

print(list_concatenator(['item1', 3]))
&gt;&gt;&gt; item1 and 3

print(list_concatenator(['item1']))
&gt;&gt;&gt; item1 

print(list_concatenator([]))
&gt;&gt;&gt; Your list is empty!


The program also takes care of the Oxford comma, where lists with two items do not have commas (e.g. apples and bananas) but lists with more than two items are separated with commas (apples, bananas, and cakes). Here are some useful links that help us understand what Oxford commas really are and when they should be used - 


https://www.grammarly.com/blog/comma-before-and/
https://en.wikipedia.org/wiki/Serial_comma


Overall, I believe formatting was the main problem in your code.



EDIT - 

In the comments section above, @Ilmari Karonen correctly mentions that the usage of " ' " in the book is the book's way of writing string literals. Therefore, I have edited my answer to make this change (i.e. remove unnecessary quotes). But if you require these quotes, then you could always wrap the string in double quotes, like this - f"'{your_list[0]} and {your_list[1]}'" or this - "'{0} and {1}'".format(your_list[0], your_list[1]). 

Another let-down in your code is the use of inconsistent parentheses here,

(', '.join((map(str,your_list[:-1])))) 

which could just be written as -

', '.join(map(str,your_list[:-1])). 

To remain concise and immaculate in writing programs, I suggest you have a look at PEP 8, which is Python's official style guide.

Hope this helps!