2015-06-13 54 views
0

這是我的第一個問題,所以我真誠地爲任何發佈的錯誤表示誠摯的歉意,我相信我會做出這些錯誤。我首先搜索了以前回答的問題,但我沒找到合適的解決方案,儘管我知道我可能沒有使用正確的術語或關鍵字進行搜索。如何實現函數的變體/變體

我有一個通用函數,我想在Python中快速進行評估。它被傳遞給一個優化器(fmin_cobyla),我寧願只採用一個參數。我希望能夠選擇使用可能由標誌控制的此功能的不同變體(變體?味道?)。因爲我希望它很快評估它沒有意義具有函數內的一堆if或case語句(?右),所以目前我有在圍繞此函數的定義語句變種:

if flag==1: 
    def f(x): 
     for i in range(0,len(x)*3,3): 
      A[i:i+3,i:i+3]=1/x[i/3]*np.eye(3) 
     tmp=np.linalg.solve(A,b) 
     y=somecmodulefunction(tmp) 
     return y 
elif flag==2: 
    def f(x): 
     for i in range(0,len(x)*3,3): 
      A[i:i+3,i:i+3]=x[i/3]*np.eye(3) 
     tmp=np.linalg.solve(A,b) 
     y=somecmodulefunction(tmp) 
     return y 
... 

這些功能與一行除外相同。這是做到這一點的正確方法嗎?無論如何要做到這一點,如果我有10個不同的變體,這不僅是一個冗長的笨重的代碼塊?

謝謝!

+0

給函數添加一個參數'flag',然後添加一個'if'模塊來實現不同的行爲。嘗試遵循DRY(不要重複自己)。 – TigerhawkT3

+0

如果函數需要評估10^10次,那麼函數中的語句是否會減慢其評估速度? (我在原帖中提到過) – omegamanda

+0

當然,添加一個語句會使其減慢一些非零值,但如果您擔心從簡單的'if boolean_value'命中性能,您應該編寫程序在C. – TigerhawkT3

回答

0

爲什麼你不把標誌變量作爲輸入傳遞給函數呢?

def f(x, flag): 
    for i in range(0,len(x)*3,3): 
     if flag == 1: 
      A[i:i+3,i:i+3]=1/x[i/3]*np.eye(3) 
     elif flag == 2: 
      A[i:i+3,i:i+3]=x[i/3]*np.eye(3) 
    tmp=np.linalg.solve(A,b) 
    y=somecmodulefunction(tmp) 
    return y 

如果存在的flag一個默認值,你可以使用,Default Argument Values

def f(x, flag=1): 
    for i in range(0,len(x)*3,3): 
     if flag == 1: 
      A[i:i+3,i:i+3]=1/x[i/3]*np.eye(3) 
     elif flag == 2: 
      A[i:i+3,i:i+3]=x[i/3]*np.eye(3) 
    tmp=np.linalg.solve(A,b) 
    y=somecmodulefunction(tmp) 
    return y 

所以,當你這樣做,f(10),功能f()將使用flag等於1執行。

如果要使用另一個flag值,則可以簡單地執行:f(10,2)

0

試着儘可能少地重複自己。這意味着只需指定差異,即該表達式的反轉。其餘的都是一樣的。如果你想改變計算方式,那麼你只需要在一個地方做出改變。

def f(x, flag): 
    for i in range(0,len(x)*3,3): 
     temp = x[i/3]*np.eye(3) 
     if flag-2: 
      temp = 1/temp 
     A[i:i+3,i:i+3] = temp 
    tmp=np.linalg.solve(A,b) 
    y=somecmodulefunction(tmp) 
    return y 

flag2,該if分支不會被執行,因爲2-2等於0,一個falsey值。當flag1時,將執行if分支,因爲1-2等於-1,這是一個真值。但是,我建議使用布爾標誌(即期望值爲TrueFalse),因此您可以僅執行if flag:並且有True表示要反轉。

+0

我認爲通過'flag'是一個很好的解決方案,但是我覺得這個測試的特定實現有點模糊(更明確的東西可能會更好):但是如果你這樣做,爲什麼不簡單地'A [i:i + 3 ,i:i + 3] = x [i/3] **(2 * flag-3)* np.eye(3)'? – xnx