這是的不是生成排列。它生成n維笛卡爾產品。 (在這個過程中,它也產生所有排列,但算法生成只排列會有所不同。)
這是一個有點難以解釋它是如何工作的,但如果你看看輸出較小的輸入,你可以看到發生了什麼。考慮'abc'
和[None] * 3
輸出(我修改了代碼作爲一個真正的生成):
>>> def generate(charlist,state,position):
... for i in charlist:
... state[position] = i
... if position == (len(state)-1):
... yield "".join(state)
... else:
... for j in generate(charlist,state,position+1):
... yield j
...
>>> print list(generate('abc', [None] * 3, 0))
['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 'acc',
'baa', 'bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc',
'caa', 'cab', 'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc']
正如你所看到的,什麼情況是,最初,generate
自稱爲三次,遞增每次position
(從0
至1
至2
)。每次通過遞歸循環時,它會將'a'
置於當前位置,並測試它是否已到達state
列表的末尾。如果是這樣,它會得出結果,並且不是自己調用。
在這種情況下,當發生這種情況時,position == 2
。現在for
循環開始,將'b'
和'c'
存儲在state[2]
中,併產生這些狀態中的每一個。然後該功能結束,並且控制返回給調用者,其中position == 1
。呼叫者然後繼續其for循環;它集state[1] = 'b'
然後,因爲position
是在state
列表的末尾不再,它再次調用自身......現在position == 2
,並在for循環設置state[2] == 'a'
,'b'
,'c'
,等等。
順便說一句,如果你想計算笛卡爾乘積的蟒蛇,這裏是一個不錯的方式,不需要你的讀者解析出遞歸算法:
>>> import itertools
>>> [''.join(c) for c in itertools.product('abc', 'abc', 'abc')]
['aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 'acc',
'baa', 'bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc',
'caa', 'cab', 'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc']
你也可以做
>>> [''.join(c) for c in itertools.product(*['abc'] * 3)]
您永遠不會返回該函數,因此它不能正確遞歸。 –
我們走了,確保它是完美的,代碼的作品也是如此。也編輯標題,以配合你所說的Jakob。 – TheEliteNoob
@Jakob Bowyer遞歸函數是調用自身的任何函數。 –