revive a generator

Yingjie Lan lanyjie at yahoo.com
Fri Oct 21 04:49:59 EDT 2011





----- Original Message -----
> From: Chris Angelico <rosuav at gmail.com>
> To: python-list at python.org
> Cc: 
> Sent: Friday, October 21, 2011 4:27 PM
> Subject: Re: revive a generator
> 
> On Fri, Oct 21, 2011 at 7:02 PM, Yingjie Lan <lanyjie at yahoo.com> wrote:
>>  What if the generator involves a variable from another scope,
>>  and before re-generating, the variable changed its value.
>>  Also, the generator could be passed in as an argument,
>>  so that we don't know its exact expression.
>> 
> 
> There's actually no way to know that the generator's even
> deterministic. Try this, for instance:
> 
>>>>  g=(input("Enter value %d or blank to stop: "%n) for n in 
> range(1,11))
>>>>  for s in g:
>     if not s: break
>     print("Processing input: "+s)
> 
> It may not be particularly useful, but it's certainly legal. And this
> generator cannot viably be restarted. 

Depends on what you want. If you want ten more inputs from user,
reviving this generator is certainly a good thing to do.

> The only way is to cast it to
> list first, but that doesn't work when you have to stop reading
> expressions from the generator part way.
> 
> What you could perhaps do is wrap the generator in something that
> saves its values:
> 
>>>>  class restartable(object):
>     def __init__(self,gen):
>         self.gen=gen
>         self.yielded=[]
>         self.iter=iter(self.yielded)
>     def restart(self):
>         self.iter=iter(self.yielded)
>     def __iter__(self):
>         return self
>     def __next__(self): # Remove the underscores for Python 2
>         try:
>             return self.iter.__next__()
>         except StopIteration:
>             pass
>         ret=self.gen.__next__()
>         self.yielded.append(ret)
>         return ret
> 
>>>>  h=restartable(g)
>>>>  for i in h:
>     if not i: break
>     print("Using: ",i)
>>>>  h.restart()
>>>>  for i in h:
>     if not i: break
>     print("Using: ",i)
> 
> Complicated, but what this does is returns a value from its saved list
> if there is one, otherwise returns a value from the original
> generator. It can be restarted as many times as necessary, and any
> time you read "past the end" of where you've read so far, the 
> original
> generator will be called upon.
> 
> Actually, this model might be useful for a repeatable random-number
> generator. But those are more efficiently restarted by means of
> reseeding the PRNG.
> 


Sure. Or you would like to have the next few random numbers with 
the same PRNG. 

These two cases seem to be strong use cases for reviving a generator.

Yingjie



More information about the Python-list mailing list