2014-10-07 95 views
2

我想(僞)從列表中隨機選擇一個符合條件的對象。我有一個做這行的一個標準,我需要一個功能:在Python中隨機選擇條件

from random import randint 
def choose(array): 
    return array[randint(0,len(array)-1)] 
def choose_c(array): 
    result = 'r' 
    while result[-1] == 'r': 
     result = choose(array) 
    return result 

但我希望有一個新的標準,每次我需要寫一個新的功能。有一種更簡單的方法嗎?

+0

是否所有的標準都符合相同的模式?也就是說,您是否可以在'choose_c'中添加一個參數來反映您想要拒絕哪個符號?在你的例子中,你繪製樣本,直到你拒絕「r」。這是唯一的約束條件,你會放在可以繪製的東西上,還是將約束的分類類型改變幷包含不同的功能? – ely 2014-10-07 23:49:45

+0

另外,如果可以的話,可以考慮在'random'中使用其他一些函數,比如'sample',而不是自己編寫。 – ely 2014-10-07 23:51:07

+0

沒有標準不同檢查不同的字母和不同的字母模式。 – 2014-10-08 00:03:40

回答

2

一種方法是讓你的choice_c函數接受一個可調用函數,它將在隨機採樣結果上評估,直到它計算到False,此時隨機採樣將被返回。

def choice_c(array, criterion=None): 
    result = choose(array) 
    if criterion: 
     while criterion(result): 
      result = choose(array) 

    return result 

def r_criterion(some_sample): 
    return some_sample == "r" 

def gt5_criterion(some_sample): 
    return some_sample > 5 

choice_c(array, r_criterion) 
choice_c(array, gt5_criterion) 

這也可以使用dropwhile和/或takewhileitertools模塊來完成,如果這將頻繁使用,它可能是值得作出choose功能的行爲作爲發電機使用此實現。

from itertools import dropwhile 

def choose(array): 
    while True: 
     yield array[randint(0,len(array)-1)] 

def choice_c(array, criterion=None): 
    gen = choose(array) 
    return next(dropwhile(criterion, gen)) if criterion else next(gen) 

當然,在這兩種情況下,這個地方的負擔,你寫出好的單元測試,或以其他方式確保了標準的功能意義上的數組內容,任何錯誤都正確處理,而您不會在while部分循環無限生成器...

1

謝謝。我發現我一直在尋找的答案:

from random import randint 
def choose(array): 
    return array[randint(0,len(array)-1)] 
array = ['foo','bar','baz'] 
print choose([i for i in array if i[-1] != 'r']) 

我過濾掉所有不符合標準,並從剩餘的選擇項。

+3

儘管這會起作用,但我敦促謹慎。您在這裏提供給您的「選擇」功能的參數是一個新構建的列表。如果您需要重複繪製樣本,您需要支付構建預過濾列表的費用(如您的解決方案中所示),或者採用效率稍低的抽樣方法,偶爾會拒絕某些元素(如在我的)。你只需要瞭解你在工作環境中兩者之間的權衡。但是,對於小問題,只有有限的模式可以過濾出來,這將工作得很好。 – ely 2014-10-08 00:29:03