[英]What's the most pythonic way to check to what particular range (out of many) a number belongs?
我知道我可以通过使用 concatenated if a<X<b elif b<X<C else...
来检查数字 X 是否属于特定范围(在 Y 个连续范围之外),但是是否有更简洁的 Pythonic 方式这样做?
有几种方法,这个似乎还不错:
def in_range(number : int, arange : range) -> bool:
return number in arange
ranges = [range(6), range(4, 14), range(10, 20), range(12, 34)]
results = list(filter(lambda arange : in_range(5, arange), ranges))
print(results)
[范围(0, 6), 范围(4, 14)]
你可以像这样简化它。
def in_range(number : int, ranges : List[range]) -> List[range]:
return [arange for arange in ranges if number in arange]
ranges = [range(6), range(4, 14), range(10, 20), range(12, 34)]
print(in_range(6, ranges))
[范围(0, 6), 范围(4, 14)]
您可能想即时了解它。
def in_range(number : int, start : int, stop : int) -> bool:
return number in range(start,stop)
您也可以使用any
或想要测试它的浮动,在这种情况下查看@chepner评论。
使用any
:
x = 57
ranges = [range(10), range(15,27), range(38,42), range(49, 63), range(70, 95)]
if any(x in range for range in ranges):
...
如果您不能使用range
(因为您正在测试具有非整数端点的区间),请将区间存储为元组。
ranges = [(1.5, 3.7), ...]
if any(t1 < x < t2 for t1, t2 in ranges):
如果您的连续范围很密集(意味着两者之间没有间隙),我会这样做
def get_range(boundaries, x):
for a, b in zip(boundaries, boundaries[1:]):
if a < x < b:
return a, b
# Test example
boundaries = [0, 5, 10, 15, 20]
x = 13
a, b = get_range(boundaries, x)
print(a, b) # 10 15
请注意,确切的边界不包括在任何范围内。 即get_range(boundaries, 10)
没有找到任何范围。 要解决此问题,请将a < x < b
替换为例如a <= x < b
。
如果您有很多范围,那么上面的内容非常好,而硬编码的if
- elif
链将是不切实际的。 也就是说,如果你有数百万个范围,你可能想要更聪明一点,比如实现二进制搜索。
如果您希望实现等效的 switch 语句(Python 中没有),您可以定义一个实用程序 function 以使代码更简洁和可读(即避免重复):
def switch(value):
def inRange(a,b):
return a <= value and value < b
return inRange
number = 25
case = switch(number)
if case(10,20): print("small")
elif case(20,50): print("medium")
elif case(50,90): print("large")
else: print("huge")
您也可以将其与三元运算符一起使用:
inRange = switch(number)
size = "small" if inRange(10,20) else \
"medium" if inRange(20,50) else \
"large" if inRange(50,90) else \
"huge"
print(size)
如果您的范围是连续的,您可以避免使用二等分搜索重复上边界(这将为大型范围列表提供更好的性能):
ranges = [10,20,50,90]
sizes = ["small","medium","large","huge"]
from bisect import bisect_right
size = sizes[bisect_right(ranges,number)-1]
print(size)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.