Q:

Is there a better way to accomplish this python excercise? (Beginner)

I'm just starting to learn Python and I'm going through an exercise at the end of a chapter. So far, all I've learned about in the book is the very basics, flow control, functions, and lists.
The exercise is:
Comma Code 
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 a 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.
To solve this, I use the following code (python 3.x.x). I'm wondering if there is a better way to do this. It took a little trial and error, but I fumbled through it until I got this:
myList = ['apples', 'bananas', 'tofu', 'cats']
myList2 = ['apples', 'bananas', 'tofu', 'cats', 'added1', 'added2']
def listFunc(List):
        x = 0
        for i in List:
                x += 1
                if x < len(List):
                        print(i, end=' ')
                elif x == len(List):
                        print('and ' + i)
listFunc(myList2)

A:

Another way to accomplish this would be to use slices and joins:
def listFunc(lst):
    if len(lst) == 0: return ''
    if len(lst) == 1: return lst[0]
    return ", and ".join([", ".join(lst[:-1]), lst[-1]])

Here's a more readable version of the above function using the same core concepts.
def listFunc(lst):
    if len(lst) == 0: return ''      #no elements? empty string
    if len(lst) == 1: return lst[0]  #one element? no joining/separating to do, just give it back
    firstPart = lst[:-1]             #firstPart is now everything except the last element
    retFirst = ", ".join(firstPart)  #retFirst is now the first elements joined by a comma and a space.
    retSecond = ", and " + lst[-1]   #retSecond is now ", and [last element]"
    return retFirst + retSecond;

The only potentially confusing bits here I think are the slice syntax, negative indices, and string.join
The code lst[:-1] means get everything in lst excepting the last element This is a list slice
The code lst[-1] means get the last element in lst This is negative indexing
And finally, the code ", ".join(firstPart) means get a string containing each element in firstPart separated by a comma and a space

A:

Here is a simple version of the function that doesn't use anything very "fancy" and should be understandable by a beginner. Slicing is probably the most advanced stuff here but should be ok if you went through lists. It also handles two special cases of an empty list and one-item list.
def listFunc(List):
    if len(List) == 0: return ''
    if len(List) == 1: return List[0]

    value = List[0]
    for item in List[1:-1]:
        value = value + ', ' + item
    return value + ', and ' + List[-1]

This is not the way you would normally do it in Python but should be good for learning purposes.

A:

Let's have fun with Python 3 and keep it simple:
def listFunc(myList):
    *rest, last = myList
    return ", ".join(rest) + (", and " if rest else "") + last

