我發現這個功能:的Python:翻譯印刷遞歸函數到發電機
def hanoi(pegs, start, target, n):
assert len(pegs[start]) >= n, 'not enough disks on peg'
if n == 1:
pegs[target].append(pegs[start].pop())
print '%i -> %i: %s' % (start, target, pegs)
else:
aux = 3 - start - target # start + target + aux = 3
hanoi(pegs, start, aux, n-1)
hanoi(pegs, start, target, 1)
hanoi(pegs, aux, target, n-1)
在這裏Trying to implement recursive Tower of Hanoi algorithm with arrays在計算器上。
現在我需要修改它,以便代替打印start, target, pegs
而不是每次迭代排除pegs
變量。
例如,我希望這個輸出出來的新功能(漂亮印刷)的:
>>> list(hanoi([[120, 90, 60, 30], [], []]))
[ [[120, 90, 60], [30], []],
[[120, 90], [30], [60]],
[[120, 90], [], [60, 30]],
[[120], [90], [60, 30]],
[[120, 30], [90], [60]],
[[120, 30], [90, 60], []],
[[120], [90, 60, 30], []],
[[], [90, 60, 30], [120]],
[[], [90, 60], [120, 30]],
[[60], [90], [120, 30]],
[[60, 30], [90], [120]],
[[60, 30], [], [120, 90]],
[[60], [30], [120, 90]],
[[], [30], [120, 90, 60]],
[[], [], [120, 90, 60, 30]],
]
這是我嘗試修改它:
def hanoi(pegs, start, target, n):
assert len(pegs[start]) >= n, 'not enough disks on peg'
if n == 1:
pegs[target].append(pegs[start].pop())
yield pegs
else:
aux = 3 - start - target # start + target + aux = 3
hanoi(pegs, start, aux, n-1)
hanoi(pegs, start, target, 1)
hanoi(pegs, aux, target, n-1)
但是,(輸入釘號碼因爲圖形的目的而變得更大):
>>> pegs = [[120, 90, 60, 30], [], []]
>>> print(list(hanoi(pegs, 0, 2, 4)))
[]
輸出只是一個空的列表。
試圖讓通過[:]
名單的副本沒有幫助,而且我留下很迷茫,也許print
可以隨時打印出來,但yield
被「卡住」內心深處遞歸級別,所以它產生較少的深遞歸而不是outside
。此外,用列表與append
不起作用:
def hanoi(pegs, start, target, n):
assert len(pegs[start]) >= n, 'not enough disks on peg'
out = []
if n == 1:
pegs = pegs[:]
pegs[target].append(pegs[start].pop())
out.append(pegs)
else:
aux = 3 - start - target # start + target + aux = 3
hanoi(pegs, start, aux, n-1)
hanoi(pegs, start, target, 1)
hanoi(pegs, aux, target, n-1)
return out
我也嘗試以下建議,從Python: using a recursive algorithm as a generator
def hanoi(pegs, start, target, n):
assert len(pegs[start]) >= n, 'not enough disks on peg'
if n == 1:
pegs = pegs[:]
pegs[target].append(pegs[start].pop())
yield pegs
else:
aux = 3 - start - target # start + target + aux = 3
for i in hanoi(pegs, start, aux, n-1): yield i
for i in hanoi(pegs, start, target, 1): yield i
for i in hanoi(pegs, aux, target, n-1): yield i
通過從嵌套循環for
收益,但是失敗了。
如何編寫這樣的生成器(我需要用於圖形目的)?
發電機將用於這樣的:
pegs = [[120, 90, 60, 30], [], []]
positions = hanoi(pegs, 0, 2, 4)
for position in positions:
screen.fill((255, 255, 255))
print(index, peg_history[index])
for i, pegs in enumerate(position):
display_pegs(pegs, 100 + 180*i, 300, screen)
pygame.display.update()
time.sleep(0.5)
我想你的版本(使用明確的'因爲我在Python 2中,但是我得到了>>> >>> pegs = [[120,90,60,30],[],[]]'>>> print(list(hanoi(pegs,0, 2,4)))' '[[[],[],[120,90,60,30]],[[],[],[120,90,60,30]],[[], [],[120,90,60,30]],[[],[],[120,90,60,30]],[[],[],[120,90,60,30]], [[],[],[120,90,60,30]],[[],[],[120,90,60,30]],[[],[], [120,90,60,30]],[[],[],[120,90,60,30]],[[],[],[120,90,60,30]],[[ ,[],[120,90,60,30]],[[],[],[120,90,60,30]],[[],[],[120,90,60,30]] ,[[],[],[120,90,60,30]],[[],[],[120,90,60,30]]]' – Caridorc
這就是調用'list'沒有按預期工作,我怎麼能解決這個問題? – Caridorc
我知道Python以違反直覺的方式對待列表,指向過時的對象,因此您需要'產生restult的深層複製(我們正在處理列表列表;常規副本不起作用):'但爲什麼這個問題只在使用'list'時才顯示,而不是在逐個遍歷項目時顯示? – Caridorc