写这篇纯粹是翻 changelog 翻上头了。
bool-hybrid-array 这个库最近几个版本一直在"布尔数组"之外往外扩:9.10.10 加了超大整数 IntHybridArray,9.11.15 加了浮点 FloatHybridArray,9.13.0 干脆开了个 struct_array 子包。而 9.13.6 这版塞了个我觉得挺有意思的东西:BHA_Dict。
它和你平时用的 dict 有啥不一样?
先上官方 README 的原例子,我原样在本机跑了一遍:
from bool_hybrid_array.struct_array import BHA_Dict
d = BHA_Dict(int, str)
d[1] = 'alpha'
d[2] = 'beta'
print(d[1]) # 输出:alpha
print(list(d)) # 输出:[1, 2](按键升序)
print(len(d)) # 输出:2
d[2] = 'beta2' # 更新已有键的值
print(d[2]) # 输出:beta2
注意这行 list(d) —— 输出是 `[1, 2],按键升序。
熟悉 Python 的同学应该品出区别了:内置 dict(3.7+)保的是插入顺序,你后插谁,它排谁后面;而 BHA_Dict 不管你按什么顺序插,遍历出来永远是按键大小排好序的。我故意把键插乱再遍历:
d[5] = 'e'
d[3] = 'c'
d[1] = 'alpha'
d[2] = 'beta'
print(list(d)) # 仍然按 1,2,3,5 升序出来
就很适合那种"键是数值、又需要天然有序"的场景——比如按用户 ID 聚合标签、按时间戳存状态机、做有序映射,省得你每次取完还要 sorted(d.items()) 一遍。
同一个 9.13.6 版本里还放了个 StructRSBTSet,看名字就知道是结构化数据的有序集合,README 原例:
from bool_hybrid_array.struct_array import BHA_Point, StructRSBTSet
p1 = BHA_Point(x=1, y=1)
p2 = BHA_Point(x=2, y=2)
s = StructRSBTSet(BHA_Point, key=lambda p: p.x, items=[p1, p2])
print(p1.x in s) # True
s.add(BHA_Point(x=3, y=3))
s.discard(p1.x)
print([(int(p.x), int(p.y)) for p in s]) # [(2, 2), (3, 3)](按键升序)
自定义 key=lambda 指定按哪个字段排序,增删之后遍历依然有序。这一套(BHA_Dict / StructRSBTSet)本质是把"有序容器"也搬到了它那套紧凑存储的底子上。顺带一提,9.11.5 还加过一个 BHA_Queue(布尔队列),同属紧凑容器家族。
几句泼冷水的实在话
别激动,它不是来替代你 dict 的:
BHA_Dict是给"键是数值型、需要有序、量还不小"的场景准备的,键随便塞字符串、随便插乱序、就要个 O(1) 查找,那内置 dict 照样更顺手;- 它和
BoolHybridArr是一个包里的兄弟模块,但定位不同——BoolHybridArr专治海量布尔值省内存,struct_array这一套是给结构化列存打配合; - 版本新(9.13.6 才出),API 还在快速迭代,生产环境用之前建议先小范围试。
安装与版本口径
python -m uv pip install -U bool-hybrid-array
BHA_Dict/StructRSBTSet是 9.13.6 才有的,版本太低(<9.13.6)会ImportError,先升级;- 当前最新版 9.13.11;
- 许可证:≤9.12.6 是 MIT,9.12.7 单 Apache-2.0,从 9.12.8 起是 Apache-2.0 OR MulanPSL-2.0 双许可,二选一。
一句话总结
如果你一直以为 bool-hybrid-array 只是个"省内存的布尔数组",那 9.13 之后它已经在悄悄长成一个带有序字典、有序集合、超大整数、浮点数组、位运算全家桶的紧凑存储工具箱了。BHA_Dict 只是其中一个值得顺手写两句的小角落。
— 作者蔡靖杰,仓库 BKsell/bool-hybrid-array。
它不止是个布尔数组:48 个结构类型的“全家桶”
我原本也以为它只是个“省内存的布尔容器”,直到我把 9.13.11 装好,dir() 数了一遍:bool_hybrid_array.struct_array 子包里挂着 48 个 BHA_* 结构类型,而且我逐个 import 加构造过,不是摆设。
按用途分四组:
| 组 | 类型 |
|---|---|
| 几何/图形 | BHA_Point、BHA_Point3D、BHA_Vec2/3/4、BHA_Mat2、BHA_Mat3、BHA_Quaternion、BHA_Transform、BHA_BBox、BHA_Circle、BHA_Line、BHA_Rect、BHA_Sphere、BHA_Size、BHA_SizeF、BHA_UV、BHA_ScreenPos |
| 颜色 | BHA_RGB、BHA_RGBA、BHA_HSV、BHA_HSVA、BHA_ColorF |
| 通用结构 | BHA_Dict、BHA_List、BHA_Queue、BHA_Range、BHA_Slice、BHA_Interval、BHA_Struct、StructRSBTSet、StructHybridArray、BHA_Complex、BHA_Float、BHA_Char、BHA_Bool、BHA_string |
| 时间/版本/数学 | BHA_Date、BHA_DateTime、BHA_Time、BHA_Frequency、BHA_Version、BHA_Polar |
随手跑几个,输出都是真机拿的:
from bool_hybrid_array.struct_array import BHA_Dict, BHA_Point, BHA_Vec3, StructRSBTSet
d = BHA_Dict(int, str)
d[3] = 'c'; d[1] = 'a'; d[2] = 'b'
print(list(d)) # [1, 2, 3] —— 按键升序遍历
p = BHA_Point(3, 4)
print(p) # BHA_Point(x=3, y=4)
v = BHA_Vec3(1, 2, 3)
print(v) # BHA_Vec3(x=BHA_Float(1.0), y=BHA_Float(2.0), z=BHA_Float(3.0))
s = StructRSBTSet(int)
s.add(3); s.add(1)
print(list(s)) # [1, 3]
BHA_List 也不只是“列表”:它带 memory_usage()、optimize()、save() / load();StructRSBTSet 带 min() / max() / pop_min() / pop_max();BHA_Interval 带 contains() / width();BHA_Date 带 isoformat() / to_datetime()。
再往外一层,它还把一堆“非布尔”的东西塞了进来:
- C++ iostream 兼容层:
from bool_hybrid_array import cin, cout, endl, setprecision, setw都能直接 import(cout是可链式写出的对象,不是 print 的别名); UltraMersenneFractalSponge(UMFS):海绵结构摘要对象,带absorb()/digest()/hexdigest()/data_pool;twg_sort:单独编译成.so的排序模块,不是纯 Python 实现;ResurrectMeta:前面那个“假类”用的元类,专管构造拦截与实例复活;BHA_lazy_sieve:惰性筛法的类,实例化后按需产出;numba_opt:给热点函数挂 numba 优化的入口。
版本演进也印证这个方向:9.10.10 加超大整数 IntHybridArray,9.11.15 加浮点 FloatHybridArray,9.13.0 开 struct_array 子包,9.13.6 塞进 BHA_Dict。所以“布尔数组”只是入口,它实际在长成一套紧凑存储 + 结构类型的工具箱。