缩短这种比例方法的最Pythonic方法是什么?

时间:2016-08-09 08:51:00

标签: python

我正在寻找一种以大多数Pythonic方式缩短find_equivalent()比例法的方法。

如果y号码不在0 - 2000范围内,则方法应返回0。否则,方法应找到y的范围并将相等的数字返回到范围。

def find_equivalent(y):
    if y <= 0 or y > 2000:
        return 0
    elif 0 < y <= 100:
        if y in range(1, 34):
            return 18
        if y in range(34, 67):
            return 17
        if y in range(67, 101):
            return 16
    elif 100 < y <= 200:
        if y in range(101, 134):
            return 15
        if y in range(134, 167):
            return 14
        if y in range(167, 201):
            return 13
    elif 200 < y <= 500:
        if y in range(201, 301):
            return 12
        if y in range(301, 401):
            return 11
        if y in range(401, 501):
            return 10
    elif 500 < y <= 1000:
        if y in range(501, 667):
            return 9
        if y in range(667, 834):
            return 8
        if y in range(834, 1001):
            return 7
    elif 1000 < y <= 2000:
        if y in range(1001, 1334):
            return 6
        if y in range(1334, 1667):
            return 5
        if y in range(1667, 2001):
            return 4
    .
    .
    .

2 个答案:

答案 0 :(得分:6)

您可以计算您的号码:

if 0 < y <= 200:
   return 18 - ((y - 1) // 33)
elif 200 < y <= 500:
   return 12 - ((y - 201) // 100)
elif 500 < y <= 1000:
   return 9 - ((y - 501) // 667))
elif 1000 < y <= 2000:
   return 6 - ((y - 501) // 1333)
return 0

甚至可以计算这些边界值;它们基于范围除以3。

您可以将大部分内容放入列表中并使用二分法找到正确的边界:

from bisect import bisect_left

boundaries = [0, 100, 200, 500, 1000, 2000]

def find_equivalent(y):
    if not 0 < y <= 2000:
        return 0

    index = bisect_left(boundaries, y)
    stepsize = (boundaries[index] - boundaries[index - 1]) // 3
    return 21 - (index * 3) - ((y - boundaries[index - 1] - 1) // stepsize)

或预先计算较小的范围边界,但仍然使用二分法:

boundaries = [0, 100, 200, 500, 1000, 2000]
precise_boundaries = [
    upper - ((upper - boundaries[i]) // 3 * step)
    for i, upper in enumerate(boundaries[1:])
    for step in range(2, -1, -1)]

def find_equivalent(y):
    if not 0 < y <= 2000:
        return 0
    return 18 - bisect_left(precise_boundaries, y)

答案 1 :(得分:0)

我建议使用两个列表,一个包含范围的值,另一个包含返回值,即

rangelist = [0, 1, 34, 67, 100 (etc)]
returnlist = [18, 17, 16 (etc)]

然后,您可以找到距离rangelist最近的y条目,并从returnlist中选择匹配的项目。