【问题标题】:Yield usage in recursive manner以递归方式使用产量
【发布时间】:2018-05-21 13:22:17
【问题描述】:

我在玩yield,我编写了一个函数,它接受 3 个数字和一个限制,并以特定方式计算它们(计算并不重要,但可以在下面的代码中看到)。

values = []

def compute(limit, a, b, c):
    if a <= limit:
        print("Got {}, {}, {}".format(a, b, c))
        values.append([a, b, c])
        compute(limit, b*c, a*c, a*b)
    else:
        print("Process ended")


compute(9999, 2, 3, 4)
print(values)

这可行,并产生输出:

Got 2, 3, 4
Got 12, 8, 6
Got 48, 72, 96
Got 6912, 4608, 3456
Process ended
[[2, 3, 4], [12, 8, 6], [48, 72, 96], [6912, 4608, 3456]]

但是,我确信这可以通过使用 yield 来完成 - 主要是 values 列表创建部分,如您所见,它是由我在函数中手动填充的。

我之所以费心,就是为什么首先使用yield - 在这里没关系,但如果我的任务需要这个列表中的第 100000 个值怎么办 - 将它作为一个整体构建是考虑到我不想要以前的 99999 值,这不是必需的,甚至是愚蠢的......

我尝试使用类似的东西:

def compute_y(a, b, c):
    while True:
        yield b*c, a*c, b*a

for a, b, c in compute_y(2, 3, 4):
    if a > 9999:
        break

问题在于for 中的数字始终相同(2、3 和 4),因此它永远不会达到其他值,因此它是一个无限循环。

tl;dr - 我可以在这里使用 yield 来使算法更有效地处理更大的列表吗?

【问题讨论】:

    标签: python python-3.x yield


    【解决方案1】:

    是的,您需要为下一次循环迭代分配新值:

    def compute_y(a, b, c):
        while True:
            yield a, b, c
            a, b, c = b*c, a*c, b*a
    

    【讨论】:

    • 等等,yield 不像return 那样工作,只是省略了后者并直接进入标题?
    • @Sqoshu:生成器会暂停,直到请求一个值;然后他们跑到下一个yield。这可能会有所帮助:ideone.com/0mPrW5
    【解决方案2】:

    好的,整个问题是因为我认为yield 的工作方式类似于return 不关心yield 之后的后面几行。

    使用yield(由Ry-给出的提示)的整个过程是这样的:

    def compute_y(a, b, c):
        while True:
            yield a, b, c
            a, b, c = b*c, a*c, b*a
    
    
    for a, b, c in compute_y(2, 3, 4):
        if a < 9999:
            print(a, b, c)
        else:
            break
    

    输出:

    2 3 4
    12 8 6
    48 72 96
    6912 4608 3456
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-09
      • 1970-01-01
      • 2019-01-15
      • 1970-01-01
      • 1970-01-01
      • 2011-10-09
      • 2021-01-30
      • 1970-01-01
      相关资源
      最近更新 更多