A generator expression like this:
my_nums = (item for item in [1, 2, 3, 4, 5, 6, 7])
is syntax sugar for something like this:
def generator(iterable):
for item in iterable:
yield item
my_nums = generator([1, 2, 3, 4, 5, 6, 7])
The forloop itself is equivalent to something like this:
while True:
try:
item = next(my_nums)
except StopIteration:
break
else:
print(item)
Since gg = list(iterable)
is something like:
gg = []
for item in my_nums:
gg.append(item)
The problem is that the first time you loop over the generator expression, it is exhausted. If you try to loop over it again, it will just raise StopIteration
and break the loop.
For example:
>>> my_nums = (i for i in [1, 2])
>>> list(my_nums)
[1, 2]
>>> list(my_nums)
[]
>>> next(my_nums)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
See how the second time you call list(my_nums)
it returns an empty list? This is because the generator is exhausted. You can see how it raises StopIteration
if you try to fetch the next item from it.