嘿所有,我正在研究一个递归生成器来创建一个数字的固定整数分区,我对一个范围问题感到困惑。
代码类似于此代码段。
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[:]
传递给递归调用),但我仍然不理解上述行为。
为什么打印报表和收益率值不同?
答案 0 :(得分:2)
我猜你正在改变数组,所以当你打印时它有一个特定的值,那么下次你打印它时实际上已经更新了值,依此类推。最后,你有5个对同一个数组的引用,所以当然你有5次相同的值。
答案 1 :(得分:2)
print语句显示该特定时间点的列表。您的代码在运行时更改了列表,因此当您在最后检查列表时,您会看到它的值。
您可以通过单步执行此操作:
>>> 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]
答案 2 :(得分:2)
列表是可变对象,如果传入列表,并且生成器对该列表执行就地操作,那么最后对列表的所有引用都将指向同一列表。
答案 3 :(得分:0)
print和yield语句不同,因为只有一个print语句,而有2个yield。试试这个:
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]]
您会看到最后的收益是您的答案,因为您一直在传递相同的列表而不是复制。