(Learner-here) Lists + Functions = headache

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun May 5 21:31:48 EDT 2013


On Sun, 05 May 2013 17:59:15 -0700, Bradley Wright wrote:

> Hey guys and gals doing this tutorial(codecademy) and needed a bit help
> from the experienced.
> 
> I'm writing a function that takes a list(one they supply during runtime)
> here's what my function is supposed to do
> 
> 1. for each instance of the string "fizz" make a count 
> 2. Finally return that count
> 
> here's my code:
> 
> def fizz_cout(x):
>     count = 0
>     for item in x:
>         while item == "fizz":
>             count += 1
>             return count
> 
> Please remember that i am a eager beginner, where am i going wrong?

Lots of places, sorry. The first thing you're doing is hoping that we 
will guess what error you are getting. In this case, it so happens that 
we can, but that will not always be the case. You should always give us 
the code (which you have done), the data it is running on, the expected 
result, and the actual result. Within reason: don't bombard us with 
10,000 lines of code and 3MB of data.

Now, moving on to your function: try walking through it yourself in your 
head. You start off by defining a value, then start iterating over each 
value in x, one at a time.


    count = 0
    for item in x:

Suppose x = ["buzz", "fizz", "buzz", "fizz"]. Then you should get a 
result of 2. So far, you start with count = 0. Then you enter the for 
loop, and item gets the value "buzz". The next line enters a while loop:

        while item == "fizz":

Since item does *not* equal "fizz", the body of the while loop does not 
run at all, and Python jumps past the while loop, which takes it to the 
end of the for loop. So Python goes on to the next item. This time item 
gets set to "fizz". So you enter the while loop again, only this time 
item *does* equal "fizz":

        while item == "fizz":
            count += 1
            return count


Oh-oh, trouble ahead. But luckily, you have two bugs, and they *almost* 
cancel themselves out. The first problem is that the while loop would be 
an infinite loop, going around and around and around over and over again, 
since you enter it with item == "fizz" but item always stays equal to 
"fizz". So the first two lines would keep adding one to count, over and 
over again, until count is so big your computer runs out of memory (and 
that might take *months*).

Fortunately, the very next line *almost* overcomes that bug. It doesn't 
*fix* it, but it does reduce the severity. After adding one to count the 
very first time, Python hits the line "return count", which immediately 
exits the function, jumping out of the (infinite) while loop and the for-
loop. So your function always returns either 0 (if there are no "fizz" in 
the list at all) or 1 (if there is any "fizz").

So, you have two problems, and they both need to be fixed:

1) The "return count" line must not happen until the for-loop has 
completed looking at each item in the list. So it must be outside the for-
loop, not inside it. Remember that Python decides what is inside the loop 
by its indentation.

2) You don't want an infinite loop inside the for-loop. There is no need 
to have two loops at all. The outer for-loop is sufficient. You look at 
each item *once*, not over and over again, and decide *once* if you 
should add one to count, then go on to the next item.


-- 
Steven



More information about the Python-list mailing list