Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > revive a generator

Reply
Thread Tools

revive a generator

 
 
Yingjie Lan
Guest
Posts: n/a
 
      10-20-2011
Hi,

it seems a generator expression can be used only once:

>>> g = (x*x for x in range(3))
>>> for x in g: print x

0
1
4
>>> for x in g: print x #nothing printed
>>>


Is there any way to revive g here?

Yingjie
 
Reply With Quote
 
 
 
 
Paul Rudin
Guest
Posts: n/a
 
      10-20-2011
Yingjie Lan <> writes:

> Hi,
>
> it seems a generator expression can be used only once:
>
>>>> g = (x*x for x in range(3))
>>>> for x in g: print x

> 0
> 1
> 4
>>>> for x in g: print x #nothing printed
>>>>

>
> Is there any way to revive g here?
>


Generators are like that - you consume them until they run out of
values. You could have done [x*x for x in range(3)] and then iterated
over that list as many times as you wanted.

A generator doesn't have to remember all the values it generates so it
can be more memory efficient that a list. Also it can, for example,
generate an infinite sequence.





 
Reply With Quote
 
 
 
 
Yingjie Lan
Guest
Posts: n/a
 
      10-21-2011




----- Original Message -----
> From: Paul Rudin <>
> To: python-
> Cc:
> Sent: Thursday, October 20, 2011 10:28 PM
> Subject: Re: revive a generator
>
> Yingjie Lan <> writes:
>
>> Hi,
>>
>> it seems a generator expression can be used only once:
>>
>>>>> g = (x*x for x inrange(3))
>>>>> for x in g: print x

>> 0
>> 1
>> 4
>>>>> for x in g: print x #nothing printed
>>>>>

>>
>> Is there any way torevive g here?
>>

>
> Generators are like that - you consume them until they run out of
> values. You could have done [x*x for x in range(3)] and then iterated
> over that list as many times as you wanted.
>
> A generator doesn't have to remember all the values it generates so it
> can be more memory efficient that a list. Also it can, for example,
> generate an infinite sequence.
>
>

Thanks a lot to all who answered my question.*
I am still not sure why should we enforce that*
a generator can not be reused after an explicit*
request to revive it?
 
Reply With Quote
 
Chris Angelico
Guest
Posts: n/a
 
      10-21-2011
On Fri, Oct 21, 2011 at 12:46 PM, Yingjie Lan <> wrote:
>
> Thanks a lot to all who answered my question.
> I am still not sure why should we enforce that
> a generator can not be reused after an explicit
> request to revive it?


Here's an example of an explicit request to revive the generator:

>>> g = (x*x for x in range(3))
>>> for x in g: print x

0
1
4
>>> g = (x*x for x in range(3)) # revive the generator
>>> for x in g: print x #now this will work

0
1
4

ChrisA
 
Reply With Quote
 
Paul Rudin
Guest
Posts: n/a
 
      10-21-2011
Yingjie Lan <> writes:

> ----- Original Message -----
>> From: Paul Rudin <>


>> Generators are like that - you consume them until they run out of
>> values. You could have done [x*x for x in range(3)] and then iterated
>> over that list as many times as you wanted.
>>
>> A generator doesn't have to remember all the values it generates so it
>> can be more memory efficient that a list. Also it can, for example,
>> generate an infinite sequence.
>>
>>

> Thanks a lot to all who answered my question.Â*
> I am still not sure why should we enforce thatÂ*
> a generator can not be reused after an explicitÂ*
> request to revive it?


The language has no explicit notion of a request to "revive" a
generator. You could use the same syntax to make a new generator that
yeilds the same values as the one you started with if that's what you
want.

As we've already discussed if you want to iterate several times over the
same values then it probably makes sense to compute them and store them
in e.g. a list (although there are always trade-offs between storage use
and the cost of computing things again).



 
Reply With Quote
 
Yingjie Lan
Guest
Posts: n/a
 
      10-21-2011
----- Original Message -----

> From: Paul Rudin <>
> To: python-
> Cc:
> Sent: Friday, October 21, 2011 3:27 PM
> Subject: Re: revive a generator
>
>
> The language has no explicit notion of a request to "revive" a
> generator. You could use the same syntax to make a new generator that
> yeilds the same valuesas the one you started with if that's what you
> want.
>
> As we've already discussed if you want to iterate several times over the
> same values then it probably makes sense to compute them and store them
> in e..g. a list (although there are always trade-offs between storage use
> and the cost of computing things again).
>
>



What if the generator involves a variable from another scope,
and before re-generating, thevariable changed its value.
Also, the generator could be passed in as anargument,
so that we don't know its exact expression.

>>> vo = 34
>>>*g = (vo*x for x in range(3))
>>> def myfun(g):

for i in g: print(i)
vo *+= 3
revive(g) #best if revived automatically
for i in g: print(i)
myfun(g)

Yingjie
 
Reply With Quote
 
Yingjie Lan
Guest
Posts: n/a
 
      10-21-2011
----- Original Message -----

> From: Paul Rudin <>
> The language has no explicit notion of a request to "revive" a
> generator. You could use the same syntax to make a new generator that
> yeilds the same values as the one you started with if that's what you
> want.
>
> As we've already discussed if you want to iterate several times over the
> same values then it probably makes sense to compute them and store them
> in e.g. a list (although there are always trade-offs between storage use
> and the cost of computing things again).
>


Oops,my former reply has the code indentation messed up*
by the mail system.. Here is a reformatted one:


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 thatwe don't know its exact expression.

>>> vo = 34
>>>*g = (vo*xfor x in range(3))
>>> def myfun(g):

* * * * * * for i in g: print(i)
* * * * * **vo *+= 3
* * * * * **revive(g) #best if revived automatically
* * * * * **for i in g: print(i)
>>> myfun(g)



Yingjie
 
Reply With Quote
 
Paul Rudin
Guest
Posts: n/a
 
      10-21-2011
Yingjie Lan <> writes:

>
>
> 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.
>
>>>> vo = 34
>>>>Â*g = (vo*x for x in range(3))
>>>> def myfun(g):

> Â* Â* Â* Â* Â* Â* for i in g: print(i)
> Â* Â* Â* Â* Â* Â*Â*vo Â*+= 3
> Â* Â* Â* Â* Â* Â*Â*revive(g) #best if revived automatically
> Â* Â* Â* Â* Â* Â*Â*for i in g: print(i)
>>>> myfun(g)

>
>



I'm not really sure whether you intend g to yield the original values
after your "revive" or new values based on the new value of vo. But
still you can make a class that supports the iterator protocol and does
whatever you want (but you can't use the generator expression syntax).

If you want something along these lines you should probably read up on
the .send() part of the generator protocol.

As an aside you shouldn't really write code that uses a global in that
way.. it'll end up biting you eventually.

Anyway... we can speculate endlessly about non-existent language
constructs, but I think we've probably done this one to death.
 
Reply With Quote
 
Chris Angelico
Guest
Posts: n/a
 
      10-21-2011
On Fri, Oct 21, 2011 at 7:02 PM, Yingjie Lan <> 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. 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.

ChrisA
 
Reply With Quote
 
Yingjie Lan
Guest
Posts: n/a
 
      10-21-2011
----- Original Message -----

> From: Paul Rudin <>
>
> I'm not really sure whether you intend g to yield the originalvalues
> after your "revive" or new values based on the new value of vo.* But
> still you can make a class that supports the iterator protocol and does
> whatever you want (but you can't use the generator expression syntax).
>
> If you want something along these lines you should probably read up on
> the .send() part of the generator protocol.
>
> As an aside you shouldn't really write code that uses a global in that
> way... it'll end up biting you eventually.
>
> Anyway... we can speculate endlessly about non-existent language
> constructs, but I think we've probably done this one to death.
> --



Maybe no new language construct is needed:
just define that x.send() revives a generator.

Yingjie
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Please help. Trying to revive an old pc. knowledgeable user STUMPED! edwardecarr@gmail.com Computer Support 5 05-15-2007 11:45 AM
Revive a dead CF card Siddhartha Jain Digital Photography 6 12-22-2005 06:58 PM
Internet Explorer Stopped Working - how to revive? SS Computer Support 3 08-26-2005 02:08 AM
how to revive a deleted file on microsoft word HuNNie NutZ Computer Support 2 04-11-2005 07:47 PM
Revive smartmedia card ? aa Digital Photography 5 05-14-2004 11:03 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57