[Tutor] Workaround for limitation in xrange()?
Kent Johnson
kent37 at tds.net
Thu Oct 12 02:49:31 CEST 2006
Alan Gauld wrote:
> "Dick Moores" <rdm at rcblue.com> wrote in message
> news:7.0.1.0.2.20061010102836.06be3ae0 at rcblue.com...
>> 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?
>
>
More information about the Tutor
mailing list