Velocity Reviews > strange list comprehension on generator

# strange list comprehension on generator

Roland Puntaier
Guest
Posts: n/a

 08-29-2007
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

Bjoern Schliessmann
Guest
Posts: n/a

 08-29-2007
No greeting, no text? Pity.

Roland Puntaier wrote:

> 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

--
BOFH excuse #284:

Electrons on a bender

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=
Guest
Posts: n/a

 08-29-2007
> #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?=
Guest
Posts: n/a

 08-29-2007
> #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

attn.steven.kuo@gmail.com
Guest
Posts: n/a

 08-29-2007
On Aug 29, 6:50 am, Roland Puntaier <Roland.Punta...@br-
automation.com> wrote:
> 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,

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'.

--
Hope this helps,
Steven