嘿所有,我正在递归生成器来创建一个数字的固定整数分区和我被一个作用域问题混淆。

的代码与此类似片段。

def testGen(a,n):
    if n <= 1:
        print('yield', a)
        yield a
    else:
        for i in range(2):
            a[i] += n
            for j in testGen(a,n-i-1):
                yield j

我的困惑如下所示。

>>> list(testGen([1,2],4))
yield [10, 2]
yield [10, 4]
yield [10, 7]
yield [12, 11]
yield [12, 13]
[[12, 13], [12, 13], [12, 13], [12, 13], [12, 13]]

我可以简单地通过使用数组的副本(例如,在a[:]传递给递归调用)得到正确的答案,但我仍然不明白上述行为。 为什么不同的打印语句和屈服值?

有帮助吗?

解决方案

在打印语句显示在特定时间点的列表中。当你运行你的代码更改列表,这样你的时间在结束检查列表,你看它的价值呢。

您可以通过步进通过观察这样的:

>>> g = testGen([1,2],4)
>>> g.next()
('yield', [10, 2])   # note brackets in print statement because I'm on python 2.5
[10, 2]
>>> g.next()
('yield', [10, 4])
[10, 4]
>>> g.next()
('yield', [10, 7])
[10, 7]
>>> g.next()
('yield', [12, 11])
[12, 11]
>>> g.next()
('yield', [12, 13])
[12, 13]

其他提示

我猜你是变异的阵列,所以当你打印它有一个特定的值,那么接下来你打印时间实际上已经更新的价值,等等。在结束时,你有5个引用相同的数组,所以当然你具有相同的值的5倍。

列表是可变的对象,如果你在一个列表传递和发电机名单上进行就地操作,最后到列表中的所有引用都会指向同一个列表。

在打印和产量的语句是不同的,因为你只能有一个print语句,而你有2吨的产量。尝试这样:

def testGen(a,n):
    if n <= 1:
        print('yield', a)
        yield a
    else:
        for i in range(2):
            a[i] += n
            for j in testGen(a,n-i-1):
                print('yield', j)
                yield j

>>> list(testGen([1,2],4))
('yield', [10, 2])
('yield', [10, 2])
('yield', [10, 2])
('yield', [10, 2])
('yield', [10, 4])
('yield', [10, 4])
('yield', [10, 4])
('yield', [10, 4])
('yield', [10, 7])
('yield', [10, 7])
('yield', [10, 7])
('yield', [12, 11])
('yield', [12, 11])
('yield', [12, 11])
('yield', [12, 13])
('yield', [12, 13])
('yield', [12, 13])
[[12, 13], [12, 13], [12, 13], [12, 13], [12, 13]]

您将看到最后收益是你的答案,因为你已经绕过相同的列表,而不是制作一份拷贝。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top