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 · 231 天前 · 1717 次点击
    这是一个创建于 231 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

     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 条附言  ·  230 天前

    看了所有答案,多数提及的类似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  
       231 天前
    numpy ?

    arischow
        2
    arischow  
       231 天前 via iPhone
    Jesus…
    davidpi
        3
    davidpi  
       231 天前   ❤️ 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  
       231 天前
    这也要库,你自己写个 Class 实现更快吧
    vituralfuture
        5
    vituralfuture  
       231 天前 via Android
    一个 int 有 32 位,你可以把每一位看做是一个 bool 值,你可以一次性给 32 个 bool 值赋值,还可以用按位逻辑运算单独改变其中几个位的 bool 值,如果你不需要 32 个 bool 值,很简单,约定低几位无意义。如果你需要更多的 bool 值,多来几个 int ,或者使用 long ,double
    qsnow6
        6
    qsnow6  
       231 天前
    第 3 点,可以使用 Python 自带的脚手架 https://docs.python.org/3.11/distutils/apiref.html#distutils.util.strtobool
    knightdf
        7
    knightdf  
       231 天前
    这用 bit 位实现不就好了?
    est
        8
    est  
       231 天前   ❤️ 1
    dict(zip( 'bl1 bl2 bl3'.split(), map(int, '011') ))

    这里必须用字符串的 011 因为如果你用 python 的 bit 表示法 0b011 ,则最高位的 0 会被省略。
    janus77
        9
    janus77  
       230 天前
    建议你自己实现
    提一个问题:011 是什么类型?如果是数字型,如何区分 011 和 11 ?补 0 吗?
    所以,自己实现
    fengtons
        10
    fengtons  
       230 天前 via Android
    试试 bitarray
    Elliota
        11
    Elliota  
       230 天前
    静态补全写个脚本生成 pyi 文件, 然后动态绑定 bools
    NoOneNoBody
        12
    NoOneNoBody  
       230 天前
    这么简单的事,刚才都懒得发,看 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  
       230 天前 via Android   ❤️ 1
    你说的这三个功能,访问某个 bit ,更改某个 bit ,bitmask 都能实现。除了第二点用属性来访问某个位,bitmask 是用一次 bitwise 计算来得到结果,因为更底层。bitmask 就是用来干这个的。
    用比特来储存多个 bool 值是最高效的方法,Windows 里面的文件属性,unix 下面的权限,本质上都是多个 bool 值,就是用 bitmask 来储存的。没必要去用那些复杂的数据结构,或者重新发明轮子,这是很基础的。
    kice
        14
    kice  
       230 天前 via Android
    首先是如果一个程序需要这么多状态,正常先考虑下能不能改进设计模式,让状态管理起来简单一些。
    kice
        15
    kice  
       230 天前 via Android
    @kice 为什么 Android 网页版会莫名其妙提交。。。于是接着回复

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

    ---

    回到问题

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

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