yield and while loop confusion due to unexpected outcome

Juan Garcia :

Hi guys so I was wondering why when making the make_song() function it actually worked, I thought the version I'm going to show below would not work the way it did:

def make_song(count = 99, beverage = "soda"):
    while count > 0:
            if count > 1:
                yield "{} bottles of {} on the wall.".format(count, beverage)
                count -=1
            elif count == 1:
                yield "Only {} bottle of {} left!".format(count, beverage)
                count -= 1
                yield "No more {}!".format(beverage)

hey = make_song(5, "coke")
print(next(hey))
print(next(hey))
print(next(hey))
print(next(hey))
print(next(hey))
print(next(hey))

my conclusion was that when count == 1 it would print:

Only 1 bottle of coke left!

No more coke!

because they were both under the same if statement. To my surprise, it worked the way I wanted it to work, by printing only "Only 1 bottle of coke left!" when the count == 1, and then when i used next() again it would print "No more coke!", I didn't expect this one to work,

why did it not print both yields when count == 1 even though they were under the same if statement?

norok2 :

The part of the code that determines when the generator gives you something is yield and not if. The if only determines which lines gets executed depending on a condition.

In practice a generator is a generalization of a function. A function returns a value once, while a generator returns as many times as a yield statement is reached. After each yield the execution is suspended, and upon the next call to next() the execution is resumed and continues until the next yield is found.

An alternative to the next() call is to use the iterator directly in a for loop, which will exhaust all possible yield endpoints.

For example:

for s in make_song(5, "coke"):
    print(s)

will give you:

5 bottles of coke on the wall.
4 bottles of coke on the wall.
3 bottles of coke on the wall.
2 bottles of coke on the wall.
Only 1 bottle of coke left!
No more coke!

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=390420&siteId=1