结合 zip 多次生成 python 引用

问题描述

我在 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。