Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:从区间到值的映射_Python_Range_Intervals - Fatal编程技术网

Python:从区间到值的映射

Python:从区间到值的映射,python,range,intervals,Python,Range,Intervals,我正在重构一个函数,给定一系列隐式定义区间的端点,该函数检查区间中是否包含一个数字,然后返回相应的(不以任何可计算的方式相关)。 现在处理该工作的代码是: if p <= 100: return 0 elif p > 100 and p <= 300: return 1 elif p > 300 and p <= 500: return 2 elif p > 500 and p <= 800: return 3 elif

我正在重构一个函数,给定一系列隐式定义区间的端点,该函数检查区间中是否包含一个数字,然后返回相应的(不以任何可计算的方式相关)。 现在处理该工作的代码是:

if p <= 100:
    return 0
elif p > 100 and p <= 300:
    return 1
elif p > 300 and p <= 500:
    return 2
elif p > 500 and p <= 800:
    return 3
elif p > 800 and p <= 1000:
    return 4
elif p > 1000:
    return 5
如果p 100和p 300以及p 500和p 800以及p 1000:
返回5
这在我看来是非常可怕的,并且缺少的是间隔和返回值都是硬编码的。
当然,任何数据结构的使用都是可能的。

尝试以下方法:

d = {(None,100): 0, 
    (100,200): 1,
    ...
    (1000, None): 5}
value = 300 # example value
for k,v in d.items():
    if (k[0] is None or value > k[0]) and (k[1] is None or value <= k[1]):
        return v
d={(无,100):0,
(100,200): 1,
...
(1000,无):5}
值=300#示例值
对于d.项()中的k,v:

如果(k[0]为None或value>k[0]),并且(k[1]为None或value,您可以尝试以下方法:

def check_mapping(p):
    mapping = [(100, 0), (300, 1), (500, 2)] # Add all your values and returns here

    for check, value in mapping:
        if p <= check:
            return value

print check_mapping(12)
print check_mapping(101)
print check_mapping(303)
与Python中的情况一样,将有更好的方法来实现这一点

def which_interval(endpoints, number):
    for n, endpoint in enumerate(endpoints):
        if number <= endpoint:
            return n
        previous = endpoint
    return n + 1
编辑:

以上是一个线性搜索。Glenn Maynard的答案将具有更好的性能,因为它使用了二分法

import bisect
bisect.bisect_left([100,300,500,800,1000], p)
这里是文档:

另一种方式

def which(lst, p): 
    return len([1 for el in lst if p > el])

lst = [100, 300, 500, 800, 1000]
which(lst, 2)
which(lst, 101)
which(lst, 1001)

这确实很可怕。如果没有硬编码的要求,它应该这样写:

which_interval([100, 300, 500, 800, 1000], 5)
if p <= 100:
    return 0
elif p <= 300:
    return 1
elif p <= 500:
    return 2
elif p <= 800:
    return 3
elif p <= 1000:
    return 4
else:
    return 5

不考虑P>1000的情况!这就是为什么我指定:“你可以试试这个”。最后一句话很讽刺,考虑到python的哲学思想,最好只有一种显而易见的方法来做某事。BUG:如果p大于最后一个端点,则不会产生任何结果。我更喜欢这句话,因为它的形式更一般化/非硬编码,而且更深入。丢掉“上一句”太多余了。是的,你是对的,我猜原始代码“灵感”BTW,你使用命令可能对一些人听起来有点粗鲁。”你可能想考虑一个谦虚的建议,你可以随意修改你的答案,注意你的答案仍然包括一个多余的代码行,而且在充分的时间内,同样的。真的令人印象深刻。超级干净,我相信也很快。它也可以很容易地扩展,以防需要一个非自然排序或其他东西作为回报,比如字符串:import-bisect n=bisect.bisect_left([1003005008001000],p)a=[“缺席”、“低”、“平均”、“高”、“非常高”、“极端”]a[n]hmmm,但这不会返回“任意值”它返回索引。如何让它返回任意值?我尝试了
p=10x=bisect.bisect_left(OrderedDict({10'a',11'b'}),p)print()
,但没有成功。
if p <= 100:
    return 0
elif p <= 300:
    return 1
elif p <= 500:
    return 2
elif p <= 800:
    return 3
elif p <= 1000:
    return 4
else:
    return 5
def make_linear_lookup(keys, values):
    assert sorted(keys) == keys
    assert len(values) == len(keys) + 1
    def f(query):
        return values[sum(1 for key in keys if query > key)]
    return f

import bisect
def make_bisect_lookup(keys, values):
    assert sorted(keys) == keys
    assert len(values) == len(keys) + 1
    def f(query):
        return values[bisect.bisect_left(keys, query)]
    return f