考虑这样的任务:
你驾驶的速度有点太快,一名警察阻止你。编写代码来计算结果,编码为int值:0 =没有票,1 =小票,2 =大票。如果速度为60或更低,则结果为0.如果速度介于61和80之间,则结果为1.如果速度为81或更高,则结果为2.
首先想到的是一堆ifs:
def caught_speeding(speed):
if speed > 80:
return 2
elif speed > 60:
return 1
else:
return 0
如果有一种方法可以获得相同的结果,并且线数较少?
答案 0 :(得分:3)
>>> from bisect import bisect_left
>>> bisect_left([60, 80], 50)
0
>>> bisect_left([60, 80], 60)
0
>>> bisect_left([60, 80], 70)
1
>>> bisect_left([60, 80], 80)
1
>>> bisect_left([60, 80], 90)
2
所以你可以拥有
def caught_speeding(speed):
bisect_left([60, 80], speed)
答案 1 :(得分:2)
解决问题的一般方法是使用binary search;你可以使用bisect
module实现一个:
import bisect
def caught_speeding(speed):
tickets = [60, 80]
return bisect.bisect_left(tickets, speed)
bisect_left
函数以最有效的方式找到速度的插入点(它会查看每个列表的 half 以查看您的速度应该适合的位置,然后再调整一半,直到找到插入点)。对于最高60的速度,您将其插入位置0,速度在61到80之间,插入位置1,其余部分将在末尾添加,位置2:
>>> import bisect
>>> tickets = [60, 80]
>>> bisect.bisect_left(tickets, 60)
0
>>> bisect.bisect_left(tickets, 61)
1
>>> bisect.bisect_left(tickets, 80)
1
>>> bisect.bisect_left(tickets, 81)
2
对于3种不同的票价值,这确实有点矫枉过正。在以后回到您的代码时,您的3分支if-elif-else
结构更容易被理解。