如何摆脱一堆ifs

时间:2015-02-04 12:25:01

标签: python

考虑这样的任务:

你驾驶的速度有点太快,一名警察阻止你。编写代码来计算结果,编码为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

如果有一种方法可以获得相同的结果,并且线数较少?

2 个答案:

答案 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结构更容易被理解。