我有遞回問題。我撰寫的函式應該遞回地生成并回傳一個名為chain. 中斷條件是當該對(remainder, quotient)已經屬于chain-list 時,則停止迭代并回傳該串列。遞回沒有完成,而是爆炸了,引發了RecursionError. 該串列不會更新并且僅包含一個術語,因此不會執行中斷條件。我不明白為什么...
我應該如何正確實施遞回步驟來更新串列?
def proper_long_division(a, b):
"""a < b"""
chain = []
block_size = len(str(b)) - len(str(a))
a_new_str = str(a) '0' * block_size
a_new = int(a_new_str)
if a_new < b:
a_new = int(a_new_str '0')
quotient = a_new // b
remainder = a_new - b * quotient
print(remainder)
#print(chain)
# breaking condition <--- !
if (remainder, quotient) in chain:
return chain
# next step
chain.append((remainder, quotient))
chain.extend(proper_long_division(remainder, b))
return chain
try:
a = proper_long_division(78, 91)
print(a)
except RecursionError:
print('boom')
這是一個遞回示例,它(應該)遵循相同的結構,但回傳的串列已更新。我不知道為什么一個代碼有效而另一個無效。
import random
random.seed(1701)
def recursion():
nrs = []
# breaking condition
if (r := random.random()) > .5:
return nrs
# update
nrs.append(r)
# recursive step
nrs.extend(recursion())
return nrs
a = recursion()
print(a)
# [0.4919374389681155, 0.4654907396198952]
uj5u.com熱心網友回復:
當你進入時proper_long_division,你做的第一件事就是chain = []。這意味著區域變數chain參考了一個新的空串列。然后你做一些不影響 的代數chain,并檢查if (remainder, quotient) in chain:。顯然,這將永遠是False,因為chain過去和現在都是空的。
下一行,chain.append((remainder, quotient))運行得很好,但請記住,只有這個proper_long_division對它的呼叫才有參考。
現在你打電話chain.extend(proper_long_division(remainder, b))。您似乎期望遞回呼叫能夠檢查和修改chain. 但是,chain在給定呼叫中參考的物件proper_long_division僅在該呼叫中可見。
為了解決這個問題,您可以使用任何遞回函式呼叫都可以看到的共享記憶體。您可以使用全域變數,但這會使函式具有不可預測的行為,因為任何人都可以修改串列。更好的方法是使用可以訪問封閉范圍內串列的嵌套函式:
def proper_long_division(a, b):
"""a < b"""
chain = {}
def nested(a, b):
while a < b:
a *= 10
quotient = a // b
remainder = a - b * quotient
key = (remainder, quotient)
if key in chain:
return chain
# next step
chain[key] = None
nested(remainder, b)
nested(a, b)
return list(chain.keys())
上面展示了一些建議的更改。乘以 10 與在右側填充零相同,因此您無需玩字串游戲。在哈希表中查找比串列快得多。由于排序很重要,因此您不能使用set. 相反,我變成chain了 a dict,它是從 python 3.6 開始訂購的,并且只使用鍵進行查找。這些值都是指單例 None。
第二個示例在一個重要方面與第一個示例的結構不匹配:您沒有將其nrs用作退出標準的一部分。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/383334.html
下一篇:不使用遞回重寫遞回函式
