我已经在这里看到了一些排列代码的帖子,但我还没有真正找到一个好的逐步了解实际发生的事情。如果有人能够解释这段代码的每一步实际发生的事情,我将非常感激。我似乎无法绕过它。我正在查看的代码是Python,来自http://snippets.dzone.com/posts/show/753。
def all_perms(str):
if len(str) <=1:
yield str
else:
for perm in all_perms(str[1:]):
for i in range(len(perm)+1):
yield perm[:i] + str[0:1] + perm[i:]
for p in all_perms(['a','b','c']):
print p
答案 0 :(得分:2)
def all_perms(str):
# If there is only one item, there can be only one permutation
# yield the single item
if len(str) <=1:
yield str
else:
# loop over the permutations returned by a recursive call to all_perms
# note it is passing a subset of the list passed in.
for perm in all_perms(str[1:]):
# for each returned sub-permutation insert the item that
# wasn't passed into each possible position.
for i in range(len(perm)+1):
yield perm[:i] + str[0:1] + perm[i:]
for p in all_perms(['a','b','c']):
print p
所以你传递了['a','b','c']
。
调用all_perms(['b', 'c'])
并调用all_perms(['c'])
,产生'c'。
yield
语句表示all_perms()
是generator,它调用自身意味着它正在使用recursion。
我建议使用itertools.permutations而不是该代码段。
答案 1 :(得分:1)
您看到的是iterator generator。它是一个返回一个可以循环的对象的函数。
在执行for
循环期间,执行all_perms
直至达到yield
。值yield
ed作为p
变量传递给循环。然后在all_perms
语句之后的位置继续执行yield
,其中方法上次退出。
答案 2 :(得分:1)
首先,参数str
的名称是一个糟糕的选择。这可能是因为它适用于Phyton中的各种序列类型,但它应该是seq
或其他东西以使意图明确。
如果列表的长度为&lt; = 1(空或一个元素),则返回列表(此案例只有一个解决方案)。
对于所有其他情况:
a)创建str[1:]
的所有排列(即没有head元素的列表)。
b)将头元素插入a)中创建的每个排列中的每个位置并返回结果
yield
有点像return
;主要区别在于返回当前值,并且当再次调用该函数时,它继续执行yield
之后的指令。
这样,组装结果很容易。
示例:
'a'
给出'a'
(琐碎)。
'ab'
首先'a'
首先创建b
的所有排列(只有一个:'b'
本身)。现在头部插入每个位置,所以我们最终得到'ab'
(头+列表)和'ba'
(列表+头部)。
等