strange list comprehension on generator

attn.steven.kuo at gmail.com attn.steven.kuo at gmail.com
Wed Aug 29 11:15:16 EDT 2007


On Aug 29, 6:50 am, Roland Puntaier <Roland.Punta... at 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,
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'.

--
Hope this helps,
Steven





More information about the Python-list mailing list