2011-03-25 78 views
3

我在這裏看到了一些關於排列的代碼貼子,但我還沒有真正能夠找到一個很好的循序漸進的實際發生的事情。如果有人能夠解釋這段代碼的每一步實際發生的事情,我會非常感激。我似乎無法把頭圍住它。我正在看的代碼是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 

回答

1

首先,參數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

1

你看到的是一個iterator generator。這是一個返回可以循環的對象的函數。

在執行for循環期間,執行all_perms直到達到yield的點。將值yield ed作爲p變量傳遞給循環。然後all_perms的執行繼續執行yield語句,該方法上次退出。

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

+0

謝謝,這非常有幫助。我知道itertools.permutations,但我真的只是想更好地瞭解我發佈的代碼中發生了什麼。再次感謝! – bb89 2011-03-25 17:09:43

相關問題