Why does creating a list with the same generator only work the first time?

Asked

Viewed 54 times

4

In Python 3.6.8, when I materialize the list, it is shown and erases. This is a bug or so it is?

>>> vet_neg
['EH01', 'EH02', 'EH03']
Categories (3, object): ['EH01', 'EH02', 'EH03']
>>> cenarios
[0, 1]
>>> vet_neg_cenarios = itertools.product(vet_neg, cenarios, cenarios)
>>> vet_neg_cenarios
<itertools.product object at 0x7f6fa16a65e8>
>>> list(vet_neg_cenarios)
[('EH01', 0, 0), ('EH01', 0, 1), ('EH01', 1, 0), ('EH01', 1, 1), ('EH02', 0, 0), ('EH02', 0, 1), ('EH02', 1, 0), ('EH02', 1, 1), ('EH03', 0, 0), ('EH03', 0, 1), ('EH03', 1, 0), ('EH03', 1, 1)]
>>> list(vet_neg_cenarios)
[]
>>> 

2 answers

5


The way you did it, that’s the way it is.

Internally, the function itertools.product work with generators and, by definition, a generator can only be consumed once.

When you do list(vet_neg_cenarios) the first time, the generator will be consumed completely so that all generated values are stored in your list. After exhausted - consumed completely - the generator will no longer have values to generate and therefore, list(vet_neg_cenarios) will be an empty list.

If you really need to keep in memory, assign the result of the first list(vet_neg_cenarios) to an object.

  • No need to keep. I had put a print before a loop for future debugging and it came up.

1

What you have is a Generator and the value in question erases from memory after you use it. For example, the elements of the variable:

pares=(k for k in range(10) if k%2==0) 

can be accessed by the method pares.__next__(), but after calling 5 times it stops working. See:

In [2]: pares.__next__()
Out[2]: 0

In [3]: pares.__next__()
Out[3]: 2

In [4]: pares.__next__()
Out[4]: 4

In [5]: pares.__next__()
Out[5]: 6

In [6]: pares.__next__()
Out[6]: 8

In [7]: pares.__next__()
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-7-fa4a719088da> in <module>
----> 1 pares.__next__()

StopIteration: 

Note that in your case, if you run print(vet_neg_cenarios.__next__()) the program will print the first element of the list. When you called the method list in Enerator, you consumed all the elements at once.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.