问题描述
我在 numpy 中有一个相当大的数组,并希望将这些值生成给管道中的下一个处理函数。我已经预先分配了 numpy 数组,因为我不想每次都分配内存。
在一个函数中,我必须产生两个值,第一个应该在之后直接使用,第二个在几个流水线阶段之后使用。
代码的简化版本如下所示:
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()
fun1
[3] [10]
[3] [11]
[3] [12]
[3] [13]
fun2
[0]
[1]
[2]
[3]
生成器总是产生相同的引用,我只是更改了基础数据。很明显,如果我将数据收集在列表中,我会看到始终相同的值,因为只存储了引用。
但是,我不明白为什么 g1
中的 fun1
不起作用,而 g
中的 fun2
可以正常工作。
编辑: 我很感激这个问题的解决方法。
编辑: 在我的应用程序中,我再次将这些迭代器传递给函数,并在几步后加入它们。
Thierry 已经有了解决方案,如果我直接使用这些值,谢谢您 :)
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)
解决方法
这是因为在 *add_ten(nums)
中进行了拆包 g1,g2 = zip(*add_ten(nums))
。
add_tens
生成器立即耗尽以创建解包列表。此列表将作为 zip
的参数,将包含:
(<your array>,<a new array containing 10>),(<your array>,<a new array containing 11>),<a new array containing 12>),<a new array containing 13>),
由 add_ten
产生。
压缩后,您将拥有:
(<your array>,<your array>,<your array>),(<a new array containing 10>,... <a new array containing 13>)
当您打印 <your_array>
的内容时,您将获得 4 个引用中的每一个的 3
,因为这是其当前内容。
在 fun2
中,当您在迭代的每一步打印数组的内容时,您将获得其连续的内容,因此为 0、1、2、3。