程序中需要用到多个布尔值来判断状态,现在用字典保存如下:
bools = {"BL1":False, "BL2":True, "BL3":True}
其实布尔值用 0 和 1 表示书写效率更高,但是可读性差,有没有库实现下面的功能:
1, bools = '011' # 等效于上面的赋值 "False", "True", "True" 2, 赋值完后可以用对象的方式访问,bools.BL1 3, 部分改写,bools = '-0-', 等于直接改写 bools.BL2 = False, 另外两个值不变
请大侠指点
看了所有答案,多数提及的类似bit mask的实现方法只能实现要求1
主题帖的格式有点错乱,这里把三点要求复制一下:
1, bools = '011' # 等效于上面的赋值 "False", "True", "True"
2, 赋值完后可以用对象的方式访问,bools.BL1
3, 部分改写,bools = '-0-', 等效 bools.BL2 = False, 两种改写方式都能用
只有8楼 @est 的方法能够实现第2点,部分实现第3点要求
dict(zip( 'bl1 bl2 bl3'.split(), map(int, '011') ))
1
Muniesa 2023-09-09 13:39:34 +08:00
|
2
arischow 2023-09-09 14:04:14 +08:00 via iPhone
Jesus…
|
3
davidpi 2023-09-09 14:39:29 +08:00 1
有一种东西叫做 bit mask……
用一个二进制整数,作为一排“开关”: `bools = 0b011` 测试最左边那个开关的状态: ``` mask = 1 << 2 bools & mask # output: 0 ``` 翻转中间那个 bit: ``` mask = 1 << 1 bools ^ mask # Output: '1' which is equivalent to '0b001' ``` |
4
SchneeHertz 2023-09-09 15:14:39 +08:00
这也要库,你自己写个 Class 实现更快吧
|
5
vituralfuture 2023-09-09 15:23:01 +08:00 via Android
一个 int 有 32 位,你可以把每一位看做是一个 bool 值,你可以一次性给 32 个 bool 值赋值,还可以用按位逻辑运算单独改变其中几个位的 bool 值,如果你不需要 32 个 bool 值,很简单,约定低几位无意义。如果你需要更多的 bool 值,多来几个 int ,或者使用 long ,double
|
6
qsnow6 2023-09-09 15:33:51 +08:00
第 3 点,可以使用 Python 自带的脚手架 https://docs.python.org/3.11/distutils/apiref.html#distutils.util.strtobool
|
7
knightdf 2023-09-09 15:42:22 +08:00
这用 bit 位实现不就好了?
|
8
est 2023-09-09 16:26:49 +08:00 1
dict(zip( 'bl1 bl2 bl3'.split(), map(int, '011') ))
这里必须用字符串的 011 因为如果你用 python 的 bit 表示法 0b011 ,则最高位的 0 会被省略。 |
9
janus77 2023-09-09 17:32:41 +08:00
建议你自己实现
提一个问题:011 是什么类型?如果是数字型,如何区分 011 和 11 ?补 0 吗? 所以,自己实现 |
10
fengtons 2023-09-09 21:31:42 +08:00 via Android
试试 bitarray
|
11
Elliota 2023-09-09 22:27:58 +08:00
静态补全写个脚本生成 pyi 文件, 然后动态绑定 bools
|
12
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) 写个闭包,只传参数就是了 |
13
davidpi 2023-09-10 00:12:25 +08:00 via Android 1
你说的这三个功能,访问某个 bit ,更改某个 bit ,bitmask 都能实现。除了第二点用属性来访问某个位,bitmask 是用一次 bitwise 计算来得到结果,因为更底层。bitmask 就是用来干这个的。
用比特来储存多个 bool 值是最高效的方法,Windows 里面的文件属性,unix 下面的权限,本质上都是多个 bool 值,就是用 bitmask 来储存的。没必要去用那些复杂的数据结构,或者重新发明轮子,这是很基础的。 |
14
kice 2023-09-10 12:25:35 +08:00 via Android
首先是如果一个程序需要这么多状态,正常先考虑下能不能改进设计模式,让状态管理起来简单一些。
|
15
kice 2023-09-10 12:33:28 +08:00 via Android
@kice 为什么 Android 网页版会莫名其妙提交。。。于是接着回复
其次可以考虑下用有限状态机框架来表达状态之间的转换。 --- 回到问题 第一点只是数据结构,背后怎么样都无所谓。bitmask ,数组,甚至是树都 ok 。 关于 bitmask 的补充,Python 原生的 int 是变长,所以不存在只能设置 32bit 限制。 第二点和第三点,既然用上了 Python ,可以看看 Python 的魔法函数。 |