strange list comprehension on generator

R

Roland Puntaier

def changeOne(aa,idx):
aa[idx]=not aa[idx]
yield aa
for i in range(idx):
for x in changeOne(aa,i):
yield x

def changeOneOrder(aa):
yield aa
for i in range(len(aa)):
for x in changeOne(aa,i):
yield x

a=[False]*3
og=changeOneOrder(a)
#this does not return the way I would expect. why?
list(og)
#returns
#[[False, False, True], [False, False, True], [False, False, True],
[False, False, True], [False, False, True], [False, False, True], [False,
False, True], [False, False, True]]


#this works as expected
a=[False]*3
og=changeOneOrder(a)
og.next()
og.next()
....

#this works as expected
def ty():
yield 1
yield 2
yield 3

tg=ty()
list(tg)

cheers, Roland
 
B

Bjoern Schliessmann

No greeting, no text? Pity.

Roland said:
def changeOne(aa,idx):
aa[idx]=not aa[idx]
yield aa
for i in range(idx):
for x in changeOne(aa,i):
yield x

def changeOneOrder(aa):
yield aa
for i in range(len(aa)):
for x in changeOne(aa,i):
yield x

Okay, two generator definitions.
a=[False]*3
og=changeOneOrder(a)
#this does not return the way I would expect. why?

What do you expect? You created a generator object and bound it
to "og".

Please always state what you expect and what really happens. Fortune
telling is not one of my hobbies (and I think I'm not alone with
that).

Regards,


Björn
 
?

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=

#this does not return the way I would expect. why?

You yield the very same list object all the times. So
when you make a later change, all earlier results will
get changed, too (since they are the same object).
Of course, it won't affect the terminal output, so you
don't see that the older values changed in the example
that you think works as expected.

HTH,
Martin
 
?

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=

#this does not return the way I would expect. why?

You yield the very same list object all the times. So
when you make a later change, all earlier results will
get changed, too (since they are the same object).
Of course, it won't affect the terminal output, so you
don't see that the older values changed in the example
that you think works as expected.

HTH,
Martin
 
A

attn.steven.kuo

def changeOne(aa,idx):
aa[idx]=not aa[idx]
yield aa
for i in range(idx):
for x in changeOne(aa,i):
yield x

def changeOneOrder(aa):
yield aa
for i in range(len(aa)):
for x in changeOne(aa,i):
yield x

a=[False]*3
og=changeOneOrder(a)
#this does not return the way I would expect. why?
list(og)
#returns
#[[False, False, True], [False, False, True], [False, False, True],
[False, False, True], [False, False, True], [False, False, True], [False,
False, True], [False, False, True]]


If you want the "intermediate" states of 'a' in
list(og), then you need to yield a copy of that list,
instead of the list itself:

def changeOne(aa, idx):
aa[idx] = not aa[idx]
yield aa[:] # <------- a copy
for i in range(idx):
for x in changeOne(aa, i):
yield x

def changeOneOrder(aa):
yield aa[:] # <------- a copy
for i in range(len(aa)):
for x in changeOne(aa, i):
yield x

a = [False] * 3
og = changeOneOrder(a)
print list(og)

Otherwise, as you've already noticed, you can
loop over the iterator and do something
with the "instantaneous" state of 'a'.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top