I have a rather big array in numpy and want to yield the values to the next processing function in the pipeline. I have preallocated numpy arrays, as I don't want to allocate memory every time.
In one function I have to yield two values, the first one should be consumed directly afterwards, the second one a few pipeline stages later.
A simplified version of the code looks like the following:
import numpy as np
def numbers():
ret = np.array([0])
for i in range(4):
ret[0] = i
yield ret
def raw(gen):
for d in gen:
yield d
def add_ten(gen):
for d in gen:
yield d, d+10
def fun1():
nums = numbers()
g1, g2 = zip(*add_ten(nums))
for n1, n2 in zip(g1, g2):
print(n1, n2)
def fun2():
nums = numbers()
g = raw(nums)
for n in g:
print(n)
print("fun1")
fun1()
print("fun2")
fun2()
The code returns the following
fun1
[3] [10]
[3] [11]
[3] [12]
[3] [13]
fun2
[0]
[1]
[2]
[3]
The generator yields always the same reference, I just changed the underlying data. It's clear, if I would collect the data in a list, I'd see always the same value, as only the reference is stored.
However, I don't understand why g1 from fun1 does not work, while g from fun2 works as expected.
Edit: I'd appreciate a workaround for this problem.
Edit: In my application I pass these iterators into functions again and join them after a few steps.
Thierry already had a solution, if I would consume the values directly, thank you for that :)
def fun3():
nums = numbers()
g1, g2 = zip(*add_ten(nums))
h1 = raw(g1)
h2 = raw(g2)
for n1, n2 in zip(h1, h2):
print(n1, n2)