我輸出了每次迭代generate_string時得到的結果,這就是我得到的。這可能會讓所有人感到困惑,因爲沒有任何行爲符合您的預期,但讓我來解釋一下Python的想法。
#1st time
current_string = ""
still_to_place = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]
我們通過傳遞上述數據,但是開始時,當我們在發生什麼事走,我們先彈出第一個陣列['a', 'b', 'c']
,我們開始通過這個彈出的陣列進行迭代。但是,由於我們叫.pop(0),我們現在只有數組的後半部分,第一遞歸調用的still_to_place.pop(0)
要使其generate_string()取得
#2nd time
current_string = "a"
still_to_place = [['d', 'e', 'f'], ['g', 'h', 'i']]
這正是在current_string和仍然第一次進行遞歸調用。現在我們將從頭開始再次執行該功能。我們再次調用pop函數,刪除第二個數組['d', 'e', 'f']
。現在我們只剩下第三個也是最後一個數組了。
#3rd time
current_string = "ad"
still_to_place = [['g', 'h', 'i']]
當我們遍歷['g', 'h', 'i']
時,因爲still_to_place現在是空的。 (我們剛剛彈出了最後一個數組。)任何對generate_string的調用將直接進入else子句,我們將打印出「ad」字符串加上剛剛彈出的數組中的值。
#4th, 5th and 6th time
still_to_place = []
current_string = "adg"
still_to_place = []
current_string = "adh"
still_to_place = []
current_string = "adi"
我們現在繼續最後一次遞歸調用停止的地方,當我們經歷第二次時。這是事情變得混亂的地方。當我們離開current_string = "a"
和still_to_place
原本是[['d', 'e', 'f'], ['g', 'h', 'i']]
,但我們已經從陣列中彈出了所有的東西。你看,數組的行爲與數字或字符串不同。陣列的所有版本都共享相同的數據。您只需更改一次數據,然後在數組使用的任何地方更改。 (對象和字典也以這種方式表現)。
因此,所有說still_to_place = []
和still_to_place
將保留爲空的剩餘的遞歸調用。 potential_items仍然有它彈出的數據['d', 'e', 'f']
。我們已經執行的步驟#4,#5,#6的「D」的字符串,所以我們可以完成我們留下的
#7th and 8th times
still_to_place = []
current_string = "ae"
still_to_place = []
current_string = "af"
再次potential_items有['a', 'b', 'c']
,我們已經執行「一」。與still_to_place不同,potential_items是一個範圍較小的局部變量。如果你知道範圍是如何工作的,那麼它會使我們爲什麼可以有多個potential_items,但它與正在使用的still_to_place是一樣的。每次我們從still_to_place中彈出一個項目時,我們會將彈出的結果添加到具有有限範圍的新潛在項目變量中。 still_to_place對於整個程序來說是全球性的,所以對still_to_place的一個改變會導致在不被預期的情況下的改變。
希望我讓事情更加混亂,而不是混亂。留下你需要更多解釋的評論。
哦,小子!感謝內聚的迴應。我很滿意,我對遞歸的理解是可以的,但是似乎我對數組的存在理解不是。您建議的解決方案與其他評論者相同(在我進一步去傳遞數組片段時,而不是更改數組)? 閱讀關於範圍傳入的噸數... –
是的,Hacoo的解決方案將是解決這個問題的好方法。切片數組時,數據將被複制,從而防止您在代碼中看到的問題。 [這篇文章](http://henry.precheur.org/python/copy_list)很好地解釋了數組正在發生什麼。此外,如果您可以單擊數字0上方的箭頭來提示答案,那就太棒了。 –