Python中字典的键可以是一个范围吗?

想做一个判断十六个风向的函数,输入角度,输出风向的字符串。感觉写十六个 if else 很不好,这个可以用字典做吗?或是其他什么方法?


Python中字典的键可以是一个范围吗?
14 回复

用除法


不行,Python字典的键不能直接是一个“范围”(比如range(1, 5))。字典的键必须是不可变可哈希的类型。

range对象本身是不可变的,可以作为键:

my_dict = {range(1, 5): "这是一个范围"}
print(my_dict[range(1, 5)])  # 输出:这是一个范围

但这样键就是整个range对象,而不是指“1到4之间的所有整数”。你不能用my_dict[3]来获取值。

如果你想要实现“用范围来匹配键”的效果,有几种实用方法:

  1. 用元组表示范围作为键
range_dict = {
    (1, 10): "第一段",
    (11, 20): "第二段"
}

def get_value(num):
    for (start, end), value in range_dict.items():
        if start <= num <= end:
            return value
    return None

print(get_value(5))   # 输出:第一段
print(get_value(15))  # 输出:第二段
  1. 使用intervaltree等第三方库(处理复杂区间时):
from intervaltree import IntervalTree

tree = IntervalTree()
tree[1:10] = "A"  # 左闭右开区间
tree[11:20] = "B"

print(tree[5])    # 输出:{Interval(1, 10, 'A')}
print(tree[15])   # 输出:{Interval(11, 20, 'B')}

总结:直接用范围匹配需要自己实现查找逻辑。

如果这些范围都互相不重合的的话,你可以自己设计一个散列函数

选范围中间值作为离散点,然后输入数据除以单位角度后四舍五入就行。

看看我的 《 Python 如何传递运算表达式》

https://hexiangyu.me/2018/04/02/pass-operation-expression/

然后你就可以优雅的消除掉无脑 if-else 的写法

<br>&gt;&gt;&gt; exp = Expression()<br>&gt;&gt;&gt; data = [1, 3, 4, 5, 6, 8, 9]<br>&gt;&gt;&gt; pick_range(data, 1 &lt; exp, exp &lt; 6)<br>[3, 4, 5]<br>&gt;&gt;&gt; pick_range(data, 1 &lt;= exp, exp &lt; 6)<br>[1, 3, 4, 5]<br>&gt;&gt;&gt; pick_range(data, 1 &lt; exp, exp &lt;= 6)<br>[3, 4, 5, 6]<br>&gt;&gt;&gt; pick_range(data, 1 &lt;= exp, exp &lt;= 6)<br>[1, 3, 4, 5, 6]<br>&gt;&gt;&gt;<br>

你这个做个 Enum 枚举不是更好吗…………

可以類似這樣子嗎?

horz, vert = cos(angle), sin(angle)

horz_desc = ''
if abs(horz) > some_threshold:
horz_desc = ‘east’ if horz > 0 else 'west’

vert_desc = ''
if abs(vert) > some_threshold:
vert_desc = ‘north’ if vert > 0 else 'south’

return ’ '.join([vert_desc, horz_desc])

In [18]: from bisect import bisect

In [19]: def windy(angle, base=[0,90,180,270,360], name="/北风 /东风 /南风 /西风"):
…: i = bisect(base, angle)
…: return name.split(’/’)[i]
…:

In [20]: windy(0)
Out[20]: '北风’

In [21]: windy(90)
Out[21]: '东风’

In [22]: windy(15)
Out[22]: '北风’

In [23]: windy(100)
Out[23]: '东风’

In [24]: windy(200)
Out[24]: '南风’

In [25]: windy(280)
Out[25]: ‘西风’

你这不就是 np.where 么。。。

字典并不限制你是一个非单射映射

这个帖子在 1L 就该结束了…

难以想象当你需要计算时间的时候又会提出什么提问…

回到顶部