有人可以解释这个python排列代码吗?

问题描述:

我在这里看到了一些关于排列的代码贴子,但我还没有真正能够找到一个很好的循序渐进的实际发生的事情。如果有人能够解释这段代码的每一步实际发生的事情,我会非常感激。我似乎无法把头围住它。我正在看的代码是Python,并且从http://snippets.dzone.com/posts/show/753有人可以解释这个python排列代码吗?

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 

首先,参数str的名称是一个不好的选择。这可能是因为它适用于Phyton中的各种序列类型,但它应该是seq或其他用于明确意图的东西。

  1. 如果列表的长度是< = 1(空或一个元素)返回列表(存在用于这种情况下只有一个溶液)。

  2. 对于所有其他情况:

    一)只是没有头元素创建的str[1:](即列表中的所有排列)。

    b)中插入在在创建的每个置换每个位置上的头元件),并返回结果

yield工作有点像return;主要区别在于返回当前值,并且当再次调用该函数时,它继续执行yield之后的指令。

这样,很容易组装结果。

实施例:

'a'给出'a'(简单)。 'ab'头的第一排('a'),然后创建b的所有排列(只有一个:'b'本身)。现在头部插入每个位置,所以我们最后输入'ab'(头+列表)和'ba'(列表+头)。

+0

谢谢!这是我正在寻找的。产量和递归的结合使我首先很难掌握,但现在它是有道理的。我知道你对str变量的看法。如果我写了它,我也不会将它命名为,但是我只是从我在原始帖子中提到的网站抓取它。再次感谢! – bb89 2011-03-25 17:07:34

+0

令人惊讶的是,当给变量赋予专有名称时,一些代码可以变得更简单;这就是我提到它的原因。 – 2011-03-25 17:09:26

你看到的是一个iterator generator。这是一个返回可以循环的对象的函数。

在执行for循环期间,执行all_perms直到达到yield的点。将值yield ed作为p变量传递给循环。然后all_perms的执行继续执行yield语句,该方法上次退出。

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而不是该片段。

+0

谢谢,这非常有帮助。我知道itertools.permutations,但我真的只是想更好地了解我发布的代码中发生了什么。再次感谢! – bb89 2011-03-25 17:09:43