我同意这个问题可以被认为是题外话,但是,这一次,这是一个需要解决的现实问题,而不是学生问题。
不幸的是,您给出的解决方案是错误的:您只考虑可以拥有“断点”值。如果您给出不同的 weight(例如 21)或 kilometer(例如 55),该函数将引发异常:
>>> calc_shipping_cost(20, 50)
98.65
>>> calc_shipping_cost(21, 55)
Traceback (most recent call last):
File "python", line 1, in <module>
File "python", line 16, in calc_shipping_cost
ValueError: 21 is not in list
表格上写着“To 50km”、“To 100km”等。所以你需要一个更宽容的函数并考虑区间:例如:[0, 50[, [50, 100[, etc.
要在间隔的有序列表中选择一个值的索引,您可以考虑使用数组二分算法。 Python 在bisect 模块中有效地实现了该算法。通常用于计算有序数组中某项的插入点。
例如:
>>> import bisect
>>> WEIGHT_BREAKPOINTS = [10, 20, 40, 60, 80, 100, 500]
>>> bisect.bisect_left(WEIGHT_BREAKPOINTS, 10)
0
>>> bisect.bisect_left(WEIGHT_BREAKPOINTS, 40)
2
>>> bisect.bisect_left(WEIGHT_BREAKPOINTS, 25)
2
对于最后一个示例,25 的插入点是索引 2(要插入到索引也是 2 的 40 之前)。
如果出现“超出范围”,您可以提出自己的异常或简单地提出ValueError。
这是一个更好的实现:
import bisect
def calc_shipping_cost(weight, kilometer):
WEIGHT_BREAKPOINTS = [10, 20, 40, 60, 80, 100, 500]
KILOMETER_BREAKPOINTS = [50, 100, 150, 200, 999]
prices = [
[84.85, 95.15, 104.45, 116.70, 122.25],
[98.65, 108.45, 117.20, 127.95, 134.60],
[112.40, 121.70, 129.95, 149.30, 153.10],
[139.95, 148.20, 155.45, 173.10, 177.80],
[153.70, 167.50, 168.20, 193.20, 196.30],
[181.25, 188.00, 193.70, 225.85, 227.15],
[208.80, 214.50, 219.20, 281.00, 282.70],
]
row = bisect.bisect_left(WEIGHT_BREAKPOINTS, weight)
col = bisect.bisect_left(KILOMETER_BREAKPOINTS, kilometer)
try:
return prices[row][col]
except IndexError:
raise ValueError(weight, kilometer)
具有以下行为:
>>> calc_shipping_cost(10, 50)
84.85
>>> calc_shipping_cost(10.0, 50)
84.85
>>> calc_shipping_cost(20, 50)
98.65
>>> calc_shipping_cost(21, 55)
121.7
>>> calc_shipping_cost(10.0, 50)
84.85
>>> calc_shipping_cost(500, 50)
208.8
>>> calc_shipping_cost(1000, 50)
Traceback (most recent call last):
File "python", line 1, in <module>
File "python", line 24, in calc_shipping_cost
ValueError: (1000, 50)