Python: how to avoid writing numerous if/elifs in a function?
I've written a function that performs as a calculator. It works for the variables below.
However I want to scale it up to handle 15 different levels
values, and 15 different sales
and cost
values. The function would apply different sales and cost calculations per level as below. (In that each calculation applies to a particular level, the calculations could potentially be defined outside the function.)
I could write numerous if/elif statements for each of the 15 levels, but that doesn't seem very Pythonic. Is there a method for programmatically scaling such a function to take many more sales, levels and costs?
For clarity's sake, the output would be the same as below (depending on the values entered of course) but the function should just be able to handle many more values.
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
it would make sense to use a dict
to associate the relevant values with each level:
levels_dict = {4 :(sale4, cost1, cost2),
5 :(sale5, cost2, cost3)}
This way levels_dict[level]
will give you the sale and two costs to use in calculations:
def sales(level, foo, bar):
sale, x_cost, y_cost = levels_dict[level]
x = x_cost + sale * foo
y = y_cost + sale * bar
...
If level in range(15)
is always true then using a list would remove the need for keys and you could use a list:
levels_data = [None, #0
None, #1
None, #2
None, #3
(18280, 224, 335),
(19180, 335, 456)]
although if level starts at 4 then this requires many place holders.
It also might be preferable to use a namedtuple
to ensure you always put the values in the correct order:
import collections
level = collections.namedtuple("level",["sale","xcost","ycost"])
levels_dict = {4 :level(sale4, cost1, cost2),
5 :level(sale5, cost2, cost3)}
This still works the same way as above but also lets you use the names instead of order:
def sales(level, foo, bar):
data = levels_dict[level]
x = data.xcost + data.sale * foo
y = data.ycost + data.sale * bar
...
Rather than using separate variables for each of your costs and sales, you should probably combine them into a list for each, or a dictionary, depending on the possible values for level. Depending on how your logic works for what costs are relevant for what levels, this may allow you to access the appropriate cost and sales entries based on the value of level
Rather than multitests ,You can organize your data in a DataFrame, for exemple :
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
in such a way that each row is associated with a level. Then your function is immediate :
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]})
链接地址: http://www.djcxy.com/p/53136.html
上一篇: python中的三角形