V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
lon91ong
V2EX  ›  Python

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

  •  
  •   lon91ong · 2023-09-09 13:32:17 +08:00 · 1998 次点击
    这是一个创建于 460 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    请大侠指点

    第 1 条附言  ·  2023-09-09 20:43:22 +08:00

    看了所有答案,多数提及的类似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') ))
    
    15 条回复    2023-09-10 12:33:28 +08:00
    Muniesa
        1
    Muniesa  
       2023-09-09 13:39:34 +08:00
    numpy ?

    arischow
        2
    arischow  
       2023-09-09 14:04:14 +08:00 via iPhone
    Jesus…
    davidpi
        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'
    ```
    SchneeHertz
        4
    SchneeHertz  
       2023-09-09 15:14:39 +08:00
    这也要库,你自己写个 Class 实现更快吧
    vituralfuture
        5
    vituralfuture  
       2023-09-09 15:23:01 +08:00 via Android
    一个 int 有 32 位,你可以把每一位看做是一个 bool 值,你可以一次性给 32 个 bool 值赋值,还可以用按位逻辑运算单独改变其中几个位的 bool 值,如果你不需要 32 个 bool 值,很简单,约定低几位无意义。如果你需要更多的 bool 值,多来几个 int ,或者使用 long ,double
    qsnow6
        6
    qsnow6  
       2023-09-09 15:33:51 +08:00
    第 3 点,可以使用 Python 自带的脚手架 https://docs.python.org/3.11/distutils/apiref.html#distutils.util.strtobool
    knightdf
        7
    knightdf  
       2023-09-09 15:42:22 +08:00
    这用 bit 位实现不就好了?
    est
        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 会被省略。
    janus77
        9
    janus77  
       2023-09-09 17:32:41 +08:00
    建议你自己实现
    提一个问题:011 是什么类型?如果是数字型,如何区分 011 和 11 ?补 0 吗?
    所以,自己实现
    fengtons
        10
    fengtons  
       2023-09-09 21:31:42 +08:00 via Android
    试试 bitarray
    Elliota
        11
    Elliota  
       2023-09-09 22:27:58 +08:00
    静态补全写个脚本生成 pyi 文件, 然后动态绑定 bools
    NoOneNoBody
        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)
    写个闭包,只传参数就是了
    davidpi
        13
    davidpi  
       2023-09-10 00:12:25 +08:00 via Android   ❤️ 1
    你说的这三个功能,访问某个 bit ,更改某个 bit ,bitmask 都能实现。除了第二点用属性来访问某个位,bitmask 是用一次 bitwise 计算来得到结果,因为更底层。bitmask 就是用来干这个的。
    用比特来储存多个 bool 值是最高效的方法,Windows 里面的文件属性,unix 下面的权限,本质上都是多个 bool 值,就是用 bitmask 来储存的。没必要去用那些复杂的数据结构,或者重新发明轮子,这是很基础的。
    kice
        14
    kice  
       2023-09-10 12:25:35 +08:00 via Android
    首先是如果一个程序需要这么多状态,正常先考虑下能不能改进设计模式,让状态管理起来简单一些。
    kice
        15
    kice  
       2023-09-10 12:33:28 +08:00 via Android
    @kice 为什么 Android 网页版会莫名其妙提交。。。于是接着回复

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

    ---

    回到问题

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

    第二点和第三点,既然用上了 Python ,可以看看 Python 的魔法函数。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2782 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 13:21 · PVG 21:21 · LAX 05:21 · JFK 08:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.