bremen_matt - 3 months ago 13
Python Question

# Python generator to list

I have a Python generator

`lexg`
which produces a list at each iteration. The code seems to work in the traditional
`for`
-loop sense, that is,

``````for i in lexg(2,2): print(i)
``````

produces:

``````[2, 0]
[1, 1]
[1, 0]
[0, 2]
[0, 1]
[0, 0]
``````

but seems to break in list comprehension, that is, both

``````list(lexg(2,2))
``````

and

``````[i for i in lexg(2,2)]
``````

produce

``````[[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0],
[0, 0]]
``````

whereas, I expect
`list(lexg(2,2))`
to produce

``````[[2, 0]
[1, 1]
[1, 0]
[0, 2]
[0, 1]
[0, 0]]
``````

The code for
`lexg`
is:

``````def lexg( n, d ):
exponent    = [0] * n;
def looper( m, totalDegree ):
r   = reversed( range( 0, d - totalDegree + 1 ) );
for j in r:
exponent[n-m] = j;
if m == 1:
yield exponent;
else:
for x in looper( m-1, totalDegree+j ): yield x
return looper( n, 0 );
``````

What is causing the empty output?

Edit/Solution

The problem, as suggested below, is the fact that the same list is returned at every step of the generator. One solution is therefore to copy the list before returning. For example, I have changed the
`yield exponent;`
line of
`lexg`
to
`yield list(exponent);`
, which resolves the problem.

As pointed out by deceze you essentially end up with a list of lists pointing to the same instance

To make it more clear, try that

``````a = list(lexg(2,2))
a[0][0] = 3
print(a)
``````

which results in

``````[[3, 0], [3, 0], [3, 0], [3, 0], [3, 0], [3, 0]]
``````
Source (Stackoverflow)