2013-04-08 54 views
0

我想知道如何在Python中執行以下操作。 如果我有一個for循環的函數,可以用if語句跳過某些數字。而不是繼續,重新運行功能

這是來自activestate.com的fisher-yates d的實現。

import random 

def shuffle(ary): 
    a=len(ary) 
    b=a-1 
    for d in range(b,0,-1): 
     e=random.randint(0,d) 
     if e == d: 
      continue 
     ary[d],ary[e]=ary[e],ary[d] 
    return ary 

現在continue只是轉到d的下一個值。我怎樣才能,而不是做continue,重新運行與原始參數ary功能?

請注意,該函數只是一些示例代碼,我很好奇如何做到這一點。 另外,如果列表很大,維護數組的副本可能不可行,所以這不是一個真正的解決方案。

+0

該列表未在位編輯... – gioi 2013-04-08 12:32:31

+0

您想在「重新啓動」該功能後繼續原始循環嗎?即你想要遞歸嗎?還是隻想放棄當前的函數並重新開始? – poke 2013-04-08 12:33:19

+0

@ioi我假設這個列表將在''做一些事情到列表''部分編輯。 – poke 2013-04-08 12:33:40

回答

2

這是一種常見的遞歸模式。然而,你的情況是比平常有點不同,因爲在這裏你需要做一個複製您的輸入列表的當你遞歸如果洗牌失敗:

import random 

def shuffle(ary): 
    initial = ary[:] 
    a=len(ary) 
    b=a-1 
    for d in range(b,0,-1): 
     e=random.randint(0,d) 
     if e == d: 
      return shuffle(initial) 
     ary[d],ary[e]=ary[e],ary[d] 
    return ary 


ary = [1,2,3,4,5,6] 
print shuffle(ary) 

使用另外請注意,Wikipedia gives a (non-recursive) python implementation of the very similar Sattolo's algorithm.

from random import randrange 

def sattoloCycle(items): 
    i = len(items) 
    while i > 1: 
     i = i - 1 
     j = randrange(i) # 0 <= j <= i-1 
     items[j], items[i] = items[i], items[j] 
    return 

如果我正確地閱讀文章,重新獲得費希爾 - 耶茨,你只是做一個簡單的變化:

from random import randrange 

def FisherYates(items): 
    i = len(items) 
    while i > 1: 
     i = i - 1 
     j = randrange(i+1) # 0 <= j <= i 
     items[j], items[i] = items[i], items[j] 
    return 
+0

沒有這個工作。如果我使'ary = [1,2,3,4,5,6]'並用'return shuffle(ary)'替換'continue',我就會得到結果'[5,3,6,4 ,2,1]'。我不認爲這應該發生,因爲'4'仍然在同一個地方,如果我正確理解代碼不應該是這樣。 – Mythio 2013-04-08 12:55:40

+0

請注意,示例代碼已更改爲我剛剛找到的實現,但問題是相同的。 – Mythio 2013-04-08 12:56:08

+0

從我可以看到的問題來看,使用'return shuffle(ary)'''''您正在重新運行帶有已修改的'ary'的'shuffle()'。而那不是我正在尋找的行爲。 – Mythio 2013-04-08 13:00:55

0
def function(list): 
    len(list)-1 
    for i in range(len(list)-1,0,-1): 
     e= randint(0,i) 
     while e > i: 
      e= randint(0,i) 
     "do something to the list" 
    return array 

0

您可以複製該參數爲一個臨時變量。然後用temp變量調用函數並使用return;

def function(list): 
listCopy = list; 
    len(list)-1 
    for i in range(len(list)-1,0,-1): 
     e= randint(0,i) 
     if e > i: 
      return function(listCopy) 
     else 
      "do something with the list" 
    return array 
+0

如果'list'將在原地改變,'listCopy'也會改變。 – poke 2013-04-08 12:35:23

+0

順便說一句,那些分號是什麼? – gioi 2013-04-08 12:36:15

+0

@poke:確切地說,你可以使用'listCopy = list(list)'來創建一個真正的新列表,但內存明智這不是一個好主意。 – Mythio 2013-04-08 12:58:04

0
def function(list): 
    for i in (a for a in range(len(list)-1,0,-1) if randint(0,a) > a): 
     #do something with list 
    #do something else with remainder. 

不是你問什麼了。只是想提醒你這種可能性。