2013-04-08 52 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. 

不是你问什么了。只是想提醒你这种可能性。