0

I'm learning Python through Automate the Boring Stuff and I'm running into a something I don't quite understand.

I'm trying to create a simple for loop that prints the elements of a list in this format: W, X, Y, and Z.

My code looks like the following:

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

def printSpam(item):
    for i in item:
        if i < len(item)-1:
            print (','.join(str(item[i])))
        else:
            print ("and ".join(str(item[len(item)-1])))
    return

printSpam(spam)

I get this error in response:

Traceback (most recent call last):
  File "CH4_ListFunction.py", line 11, in <module>
    printSpam(spam)
  File "CH4_ListFunction.py", line 5, in printSpam
    if i < len(item)-1:
TypeError: '<' not supported between instances of 'str' and 'int'

Any help is appreciated. Thanks for helping a newbie.

FlavorTownUSA
  • 11
  • 1
  • 1
  • 6
  • You are misunderstanding how `for ... in ...` works. `i` is already the string from the list, _not_ the index, thus `<` is comparing strings and integers, and `item[i]` does not make sense, either. Also, you are trying to `join` a single item! – tobias_k Aug 11 '16 at 16:23
  • You're basically doing `"s" < 4`. This makes no sense. – Martin Tournoij Aug 11 '16 at 16:23
  • In this case `i` is a string. You are trying to compare a string to the length of a list. – Harrison Aug 11 '16 at 16:24
  • Instead of looping, you can use list slices like `item[0:-1]` to get all but the last item, and `item[-1]` to get the last item. Join the first set with `,`, and then connect that with `and` to the last. – Barmar Aug 11 '16 at 16:29
  • @Barmar: argh, you beat me to it while I was answering :) – Tobia Tesan Aug 11 '16 at 16:46

1 Answers1

5

Ah, but for i in array iterates over each element, so if i < len(item)-1: is comparing a string (the array element item) and an integer (len(item)-1:).

So, the problem is you misunderstood how for works in Python.

The quick fix?

You can replace your for with for i in range(len(array)), as range works like this:

>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Thus obtaining:

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

def printSpam(item):
    for i in range(len(item)):
        if i < len(item)-1:
            print (','.join(str(item[i])))
        else:
            print ("and ".join(str(item[len(item)-1])))
    return

printSpam(spam)

The output probably won't be what you expect, though, as 'c'.join(array) uses 'c' as "glue" between the various elements of the array - and what is a string, if not an array of chars?

>>> ','.join("bananas")
'b,a,n,a,n,a,s'

Thus, the output will be:

a,p,p,l,e,s
b,a,n,a,n,a,s
t,o,f,u
cand aand tand s

We can do better anyway.

Python supports so-called slice notation and negative indexes (that start at the end of the array).

Since

>>> spam[0:-1]
['apples', 'bananas', 'tofu']
>>> spam[-1]
'cats'

We have that

>>> ", ".join(spam[0:-1])
'apples, bananas, tofu'

And

>>> ", ".join(spam[0:-1]) + " and " + spam[-1]
'apples, bananas, tofu and cats'

Therefore, you can write your function as simply

def printSpam(item):
    print ", ".join(item[0:-1]) + " and " + item[-1]

That's it. It works.

P.S.: One las thing about Python and array notation:

>>> "Python"[::-1]
'nohtyP'
Community
  • 1
  • 1
Tobia Tesan
  • 1,938
  • 17
  • 29
  • 2
    This was literally the most informative explanation on `for` notation in Python that I've read yet and I'm slightly embarrassed that I forgot the `range()` function in my code; CodeAcademy at least taught me that. I going to go back and try with a different code practice and see if I can make something different this time. Thanks for your response! – FlavorTownUSA Aug 11 '16 at 20:45