Alan Gauld wrote: > "Dick Moores" <[EMAIL PROTECTED]> wrote in message > news:[EMAIL PROTECTED] >> Encapsulate the while loop in a generator: >> def count(limit): >> n=0 >> while n<limit: >> yield n >> n += 1 >> >> All 3 are essentially the same, aren't they. Which makes me feel >> even >> dumber, because I don't understand any of them. I've consulted 3 >> books, and still don't understand the use of yield. > > Think of yield as being the same as return except that next time > you "call the function" all the state is preserved and it picks up > processing > after the yield.
A small correction - in normal use you only call the generator function once. The value it returns is a generator, an object with a next() method. It is the next() method that is called repeatedly to re-enter the function and return the next value. When there are no more values to return, the next() method raises StopIteration. For example: In [1]: def f(): yield 1 ...: In [2]: f Out[2]: <function f at 0x00F15C70> f is a generator function. The result of calling it is a generator: In [3]: p=f() In [4]: p Out[4]: <generator object at 0x00F23670> The generator p is not callable: In [5]: p() --------------------------------------------------------------------------- <type 'exceptions.TypeError'> Traceback (most recent call last) D:\Projects\e3po\<ipython console> in <module>() <type 'exceptions.TypeError'>: 'generator' object is not callable p.next() yields values, then raises StopIteration: In [6]: p.next() Out[6]: 1 In [7]: p.next() --------------------------------------------------------------------------- <type 'exceptions.StopIteration'> Traceback (most recent call last) D:\Projects\e3po\<ipython console> in <module>() <type 'exceptions.StopIteration'>: The generator also has an __iter__() method that returns the generator itself: In [9]: p.__iter__() is p Out[9]: True In other words, a generator satisfies the iterator protocol http://docs.python.org/lib/typeiter.html and it can be used any where an iterator can be used, such as in a for statement. Kent > > So first time you call count above it returns 0 > next time you call it it executes the n+= 1 and goes round the loop > again until it hits yield when it returns 1. > next time you call it executes y+=1 again, but because the state has > been remembered n goes to 2 and yield returns that > and so on until you reach n = limit at which point it just > exits with StopIteration. Here is a short example: > >>>> def y(n): > ... j = 0 > ... while j < n: > ... yield j > ... j += 1 > ... >>>> try: > ... x = y(7) > ... for n in range(20): > ... print x.next() > ... except StopIteration: > ... print 'Reached the end' > ... > 0 > 1 > 2 > 3 > 4 > 5 > 6 > Reached the end > > Does that help? > > _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor