2016-03-01 68 views
3

我寫過一個函數,可以作爲一個計算器來使用。它適用於下面的變量。Python:如何避免在函數中編寫多個if/elifs?

但是我想要擴展它以處理15個不同的levels值和15個不同的salescost值。該功能將按照以下級別應用不同的銷售和成本計算。 (因爲每個計算都適用於特定級別,所以計算可能會在函數外部定義)。

我可以爲15個級別中的每個級別編寫大量的if/elif語句,但這看起來不是Pythonic。有沒有一種方法可以通過編程來擴展這樣一個功能,以獲得更多的銷售額,等級和成本?

爲了清晰起見,輸出將與下面相同(取決於當然輸入的值),但函數應該能夠處理更多的值。

levels_list = [4, 5] # ultimately 15 values in this list 

sale4 = 18280 # ultimately 15 of these values 
sale5 = 19180 
sale6 = 22170 

cost1 = 224 # and 15 of these values 
cost2 = 335 
cost3 = 456 

def sales(level, foo, bar): 
    for level in levels_list: 
     if level == 4: 
      x = cost1 + sale4 * foo 
      y = cost2 + sale4 * bar 
      z = x + y 
     elif level == 5: 
      x = cost2 + sale5 * foo 
      y = cost3 + sale5 * bar 
      z = x + y 
      return pd.DataFrame({'Total Cost':[z], 'x_Cost':[x], 'y_Cost':[y]}) 

sales(5, 10, 10)

Total Cost x_Cost y_Cost 
0 384391  192135 192256 
+1

爲什麼不把成本和銷售價值列入清單? –

+3

您需要在數據中查找模式。例如,它是否總是'cost1 + sale(1 + 3)* foo'。然後,您可以將銷售和成本價值放入數組中,並按位置讀取數據。 –

+1

將銷售價值列入清單將修復該部分,但您如何確定使用哪些成本? –

回答

2

這將是有意義的使用dict到相關值與每個級別關聯:

levels_dict = {4 :(sale4, cost1, cost2), 
       5 :(sale5, cost2, cost3)} 

這樣levels_dict[level]會給你的銷售和兩個使用成本在計算:

def sales(level, foo, bar): 
    sale, x_cost, y_cost = levels_dict[level] 
    x = x_cost + sale * foo 
    y = y_cost + sale * bar 
    ... 

如果level in range(15)始終是真的,那麼使用列表將消除按鍵的需要,你可以使用一個列表:

levels_data = [None, #0 
       None, #1 
       None, #2 
       None, #3 
       (18280, 224, 335), 
       (19180, 335, 456)] 

雖然如果等級從4開始,那麼這需要很多佔位符。

這也可能是最好使用namedtuple,以確保您始終把值按正確的順序:

import collections 

level = collections.namedtuple("level",["sale","xcost","ycost"]) 

levels_dict = {4 :level(sale4, cost1, cost2), 
       5 :level(sale5, cost2, cost3)} 

這仍然有效與上述相同的方式,但也可以讓你使用的名稱,而不是爲了:

def sales(level, foo, bar): 
    data = levels_dict[level] 
    x = data.xcost + data.sale * foo 
    y = data.ycost + data.sale * bar 
    ... 
+0

「dict」和「namedtuple」解決方案都是完美的。欣賞全面的答案。 – RDJ

3

而不是使用單獨的變量爲每個成本和銷售的,你應該將它們組合成每個列表,或字典,這取決於級別的可能值。根據您的邏輯工作方式確定哪些成本與哪些級別相關,這可能允許您根據級別

+1

如果最低級別不是0,那麼列表的索引將會分開(特別是如果級別可能是負數),即使所有的鍵都是整數,使用字典可能會更好 –

1

的值訪問相應的成本和銷售條目。您可以將數據組織在DataFrame中,例如:

data=pd.DataFrame(np.array([[cost1,cost2,cost3],[sale4,sale5,sale6], 
[cost2,cost3,cost4],[sale4,sale5,sale6]]).T,index=[3,4,5], 
columns= ['costx','salex','costy','saley']) 

    costx salex costy saley  
3 224 18280 335 18280 
4 335 19180 456 19180 
5 456 22170 512 22170 

以這樣的方式,每一行都與一個關卡關聯。那麼你的功能是即時的:

def sales(level, foo, bar): 
     costx,salex,costy,saley=data.loc[level] 
     x = costx + salex * foo 
     y = costy + saley * bar 
     z = x + y 
     return pd.DataFrame({'Total Cost':[z], 'x_Cost':[x], 'y_Cost':[y]}) 
+0

其中'array()來自(哪裏? –