这是的不是生成排列。它生成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递归函数是调用自身的任何函数。 –