2017-01-03 24 views
1

我有一組函數可以在數據結構上運行,其中以預定的概率選擇給定的函數。我通過在列表中分配給每一個正整數,itertools.accumulate -ing的權重,然後bisect -ing到列表中做到這一點:將可變數量的參數應用於許多函數之一

func_weights = list(accumulate(weights)) 
probability = bisect(func_weights, random.random() * func_weights[-1]) 

問題涉及每一個這些功能有一個稍微不同的集合參數/參數。其中一些只需要數據結構,其中一些需要來自程序其餘部分的附加信息。現在,我建立每個呼叫到字典中的附加信息,並傳遞到函數爲func[probability](data_struct, **arguments),這樣我可以有每個函數的樣子:

funcs = [func_1, func_2, func_3, ...] 
weights = [1, 2, 3, ...] 

func_weights = list(accumulate(weights)) 
probability = bisect(func_weights, random.random() * func_weights[-1]) 
funcs[probability](data_struct, **arguments) 

# ... 

def func_1(data_s, arg_1, **kwargs): 
    # blah blah blah 

def func_2(data_s, arg_2, **kwargs): 
    # blah blah blah 

def func_3(data_s, arg_1, arg_2, **kwargs): 
    # blah blah blah 

此作品不夠好,我感到很聰明當我終於得到了這一切成立,但我改變了data_structure了一下,現在重新思考這個玩意兒的兩個部分:

  • 首先,一些參數是隨機數,所以不是在所有funcs中調用random.random(),我在build_arguments()中調用它一次。我有過這個想法嗎?

  • 第二,建立一個精心設計的開關式陳述而不是**arguments事情會更聰明嗎?分成索引,抓住func的名字,然後if - 然後是正確的函數。

實施例:

if name == 'func_1': 
    func_1(data_struct, arg_1) 
elif name == 'func_2': 
    func_2(data_struct, arg_2) 
elif name == 'func_3': 
    func_3(data_struct, arg_1, arg_2) 
# etc etc 
  • 第三,和一個小點的旁邊,所有這些功能在結構內的數據直接操作的而不是純的,。只傳入將被修改的元素而不是整個數據結構會更聰明嗎?

例子:

func_3(data_struct, arg_1, arg_2) 

# ... 

def func_3(data_s, arg_1, arg_2, **kwargs): 
    alist = data_s.alist 
    temp = alist[:arg_1] + alist[arg_2:] 
    point = random.randint(len(temp)) 
    data_s.alist[:] = temp[:point] + alist[arg_1:arg_2] + temp[point:] 

data_s[:] = func_3(data_struct.alist, arg_1, arg_2) 

# ... 

def func_3(alist, arg_1, arg_2, **kwargs): 
    temp = alist[:arg_1] + alist[arg_2:] 
    point = random.randint(len(temp)) 
    return temp[:point] + alist[arg_1:arg_2] + temp[point:] 

非常感謝!


編輯:似乎有一些混淆。我修正了一個小錯誤,但除此之外,其工作原理如3.4和3.5所述,如in this gist I just created所示。

+1

你真的嘗試過運行這些嗎? **參數不允許向函數傳遞任何數量的參數。它只允許傳遞關鍵字參數。你需要'*參數'(一顆星)。實際上,'* arguments'(或者更常見的是'* args')非常優雅。 – jbasko

+0

我剛剛發佈了一個[主要](https://gist.github.com/NoahTheDuke/6e8c88275c5e743fba971549d8b70759),展示了它的工作原理。雙星(** args)需要一本詞典,並試圖將這些條目與函數的參數相匹配,如果它們不合適,則將其餘的文件拋入「** kwargs」中。 –

回答

0

如果我對您的問題的解釋是正確的,那麼您可能希望在此基礎上進行構建。

我的解釋是,你想用正確數量的參數運行多個函數中的一個函數,並隨機選擇函數和隨機生成參數。

你必須改變函數的選擇來明顯地匹配你的概率模型。

import inspect 
import random 

def func1(): 
    pass 

def func2(): 
    pass 

def func3(): 
    pass 

functions = [ 
    func1, func2, func3 
] 

random_func = random.choice(functions) 
random_args = [random.randint(1, 10) for i in range(len(inspect.getfullargspec(random_func).args))] 
random_func(*random_args) 
相關問題