如何使这段代码更简单?

时间:2015-04-15 19:22:16

标签: python

我对此代码有一个小问题

if    3 <= y <  7: self.draw_y -= 2
elif  7 <= y < 13: self.draw_y -= 3
elif 13 <= y < 17: self.draw_y -= 4
elif 17 <= y < 23: self.draw_y -= 5
elif 23 <= y < 27: self.draw_y -= 6
elif 27 <= y < 33: self.draw_y -= 7
elif 33 <= y < 37: self.draw_y -= 8
elif 37 <= y < 43: self.draw_y -= 9
elif 43 <= y < 47: self.draw_y -= 10
....

你能帮我把这段代码变得更简单吗?

3 个答案:

答案 0 :(得分:1)

效率不高,但比较干净:

if y >= 3:
    self.draw_y -= 2
    delta = 6
    while y >= 7:
        self.draw_y -= 1
        y -= delta
        delta = 6 if delta == 4 else 4

答案 1 :(得分:1)

也许这样的事情会有所帮助:

from bisect import bisect_right

def drawshift(x, l=[3,7,13,17,23,27,33,37,43,47]):
    return bisect_right(l, x) + 1

print(drawshift(2)) # 1
print(drawshift(3)) # 2
print(drawshift(4)) # 2
print(drawshift(7)) # 3
print(drawshift(43)) # 10
print(drawshift(47)) # 11

我可以找到我使用的模块的文档here。它使用二分法算法(基本上是二进制搜索),它具有O(log n)查找时间。

可以使用条件语句非常简单地处理x < 3x >= 47等边缘情况。例如,请注意bisect_right(x)其中x低于列表的所有元素将返回0,而bisect_right(x)其中x大于或等于列表中的最高元素将为您提供len(l) + 1 }。

答案 2 :(得分:1)

这个问题的另一个解决方案是,它使用简单的算术(除法和模数),并且可以很容易地适用于矢量化,以防你正在研究:

def range_selector(num):
    q, r = divmod(num - 3, 10)
    return 2*q + 2 + (r>=4)

示例,使用numpy:

>>> import numpy as np
>>> y = np.array([3,6,7,13,14,47])
>>> range_selector(y)
array([ 2,  2,  3,  4,  4, 11])