有没有 Python 库实现批量布尔值赋值和读写操作

2023-09-09 13:32:17 +08:00
 lon91ong

程序中需要用到多个布尔值来判断状态,现在用字典保存如下:

 bools = {"BL1":False, "BL2":True, "BL3":True}

其实布尔值用 0 和 1 表示书写效率更高,但是可读性差,有没有库实现下面的功能:

1, bools = '011' # 等效于上面的赋值 "False", "True", "True" 2, 赋值完后可以用对象的方式访问,bools.BL1 3, 部分改写,bools = '-0-', 等于直接改写 bools.BL2 = False, 另外两个值不变

请大侠指点

2008 次点击
所在节点    Python
15 条回复
Muniesa
2023-09-09 13:39:34 +08:00
numpy ?

arischow
2023-09-09 14:04:14 +08:00
Jesus…
davidpi
2023-09-09 14:39:29 +08:00
有一种东西叫做 bit mask……

用一个二进制整数,作为一排“开关”:

`bools = 0b011`

测试最左边那个开关的状态:

```
mask = 1 << 2
bools & mask
# output: 0
```

翻转中间那个 bit:

```
mask = 1 << 1
bools ^ mask
# Output: '1' which is equivalent to '0b001'
```
SchneeHertz
2023-09-09 15:14:39 +08:00
这也要库,你自己写个 Class 实现更快吧
vituralfuture
2023-09-09 15:23:01 +08:00
一个 int 有 32 位,你可以把每一位看做是一个 bool 值,你可以一次性给 32 个 bool 值赋值,还可以用按位逻辑运算单独改变其中几个位的 bool 值,如果你不需要 32 个 bool 值,很简单,约定低几位无意义。如果你需要更多的 bool 值,多来几个 int ,或者使用 long ,double
qsnow6
2023-09-09 15:33:51 +08:00
第 3 点,可以使用 Python 自带的脚手架 https://docs.python.org/3.11/distutils/apiref.html#distutils.util.strtobool
knightdf
2023-09-09 15:42:22 +08:00
这用 bit 位实现不就好了?
est
2023-09-09 16:26:49 +08:00
dict(zip( 'bl1 bl2 bl3'.split(), map(int, '011') ))

这里必须用字符串的 011 因为如果你用 python 的 bit 表示法 0b011 ,则最高位的 0 会被省略。
janus77
2023-09-09 17:32:41 +08:00
建议你自己实现
提一个问题:011 是什么类型?如果是数字型,如何区分 011 和 11 ?补 0 吗?
所以,自己实现
fengtons
2023-09-09 21:31:42 +08:00
试试 bitarray
Elliota
2023-09-09 22:27:58 +08:00
静态补全写个脚本生成 pyi 文件, 然后动态绑定 bools
NoOneNoBody
2023-09-09 22:38:05 +08:00
这么简单的事,刚才都懒得发,看 append 还没解决?
keys = list('abc')
d = dict(zip(keys, map(bool, map(int, '011'))))
d |= {keys[i]:bool(int(x)) for i,x in enumerate('-0-') if x in '01'}
print(d)
如果离开了 keys 的定义域,也可以用 list(d.keys())代替,因为 dict 也是默认按输入顺序,中途没有重排过的话也没问题
想用对象,转 nametuple 或 SimleNamespace ,当然前者是只读的

直接用 pandas series 能满足全部,只是数据量不大就没必要
s = pd.Series(list('011'), index=list('abc')).astype(int)
s.update(pd.Series(list('-0-'), index=s.index).replace('-',np.nan).apply(float))
print(s.b)
写个闭包,只传参数就是了
davidpi
2023-09-10 00:12:25 +08:00
你说的这三个功能,访问某个 bit ,更改某个 bit ,bitmask 都能实现。除了第二点用属性来访问某个位,bitmask 是用一次 bitwise 计算来得到结果,因为更底层。bitmask 就是用来干这个的。
用比特来储存多个 bool 值是最高效的方法,Windows 里面的文件属性,unix 下面的权限,本质上都是多个 bool 值,就是用 bitmask 来储存的。没必要去用那些复杂的数据结构,或者重新发明轮子,这是很基础的。
kice
2023-09-10 12:25:35 +08:00
首先是如果一个程序需要这么多状态,正常先考虑下能不能改进设计模式,让状态管理起来简单一些。
kice
2023-09-10 12:33:28 +08:00
@kice 为什么 Android 网页版会莫名其妙提交。。。于是接着回复

其次可以考虑下用有限状态机框架来表达状态之间的转换。

---

回到问题

第一点只是数据结构,背后怎么样都无所谓。bitmask ,数组,甚至是树都 ok 。
关于 bitmask 的补充,Python 原生的 int 是变长,所以不存在只能设置 32bit 限制。

第二点和第三点,既然用上了 Python ,可以看看 Python 的魔法函数。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/972253

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX