Python:二进制字符串的布尔列表

Posted

技术标签:

【中文标题】Python:二进制字符串的布尔列表【英文标题】:Python: Boolean List to Binary String 【发布时间】:2014-03-30 04:08:06 【问题描述】:

在python中将布尔值列表转换为二进制字符串的最快方法是什么?

例如boolList2BinString([True, True, False]) = '0b110'.

另外,我如何将该二进制字符串转换为二进制文字?这会比直接从布尔列表转换为二进制文字需要更多时间吗?如何做到这一点?

例如boolList2Bin([True, True, False]) = 0b110.

谢谢!

【问题讨论】:

用 C 语言编写的扩展模块——为字符串预先分配空间并与 Py_True 进行引用比较——可能是最快的。 /s 说真的,“最快”的要求有多严重?您添加它是因为还是您尝试过某些东西并且速度太慢(如果是,请添加详细信息!)。 【参考方案1】:
L = [True, False, True]
''.join(map(str, map(int, L))) # '101'. 

【讨论】:

刚刚计时,这个解决方案比公认的慢三倍。虽然差异通常可能无关紧要,但问题特别是关于最快的方法来做到这一点,所以这里很重要。【参考方案2】:

将列表转换为像样的二进制文件(将是一个长整数):

number = reduce(lambda a, b: (a<<1) + int(b), [ True, True, False ])

然后,如果你真的需要一个“二进制字符串”,正如你所说,使用

bin(number)

生成该字符串。

编辑

您也可以使用此代码:

number = sum(int(bit) << position
             for (position, bit) in
             enumerate(reversed([True, True, False])))

其背后的机制与之前相同。

【讨论】:

在 Python 3+ reduce 我们移至 functools 模块。【参考方案3】:

关于您的第一个问题,您可以使用list comprehension* 和conditional expression:

>>> def boolList2BinString(lst):
...     return '0b' + ''.join(['1' if x else '0' for x in lst])
...
>>> boolList2BinString([True, True, False])
'0b110'
>>>

关于您的第二个,您不能“将该二进制字符串转换为二进制文字”。顾名思义,literals 必须按字面意思输入

>>> x = 0b110
>>>

也许您的意思是要从输出中删除引号?如果是这样,请使用print

>>> def boolList2BinString(lst):
...     return '0b' + ''.join(['1' if x else '0' for x in lst])
...
>>> boolList2BinString([True, True, False])
'0b110'
>>> print(boolList2BinString([True, True, False]))
0b110
>>>

*注意:我故意选择使用str.join 的列表推导式而不是生成器表达式,因为前者是generally faster。

【讨论】:

去掉括号。 join 可以处理生成器,因此您无需先创建list 您可以使用'01'[x] 而不是if/else,因为布尔值可以用作索引。 这是目前最有效的解决方案(至少在已发布的解决方案中),领先优势 +1 @Alfe - 您是正确的,您不需要 带有str.join 的列表。但是我在回答中给出的链接表明使用它通常更快。另外,如果你使用timeit.timeit,你会看到条件表达式比'01'[x]稍快。 哇。我的错 :( 我忽略了答案下方的 Note,抱歉。现在我想撤销我的否决票,我只能在答案改变的情况下这样做。我可以谦虚地请你做一个小的编辑只是为了让我这样做?【参考方案4】:
values = [True,False,False,True]
bin(sum(int(v)*2**i for i,v in enumerate(values[::-1]) ))

其实

In [7]: %timeit bin(sum(int(v)*2**i for i,v in enumerate(values[::-1]) ))
10000 loops, best of 3: 108 us per loop

In [8]: %timeit '0b' + ''.join(['1' if x else '0' for x in values])
100000 loops, best of 3: 5.25 us per loop

In [9]: %timeit bin(int("".join(str(int(item)) for item in values), 2))
10000 loops, best of 3: 29.5 us per loop

In [10]: %timeit bin(reduce(lambda a, b: (a<<1) + int(b), values))
10000 loops, best of 3: 31.3 us per loop

我的解决方案是最慢的 :( ...

【讨论】:

已修复 ... 小错误:P 假设 LSB 在布尔列表中至少位于右侧 但是鉴于您的测试和结果,您的答案是(其中)最好的:)【参考方案5】:
data = [True, True, False]
print bin(int("".join(str(int(item)) for item in data), 2))
# 0b110

【讨论】:

以上是关于Python:二进制字符串的布尔列表的主要内容,如果未能解决你的问题,请参考以下文章

python基础篇-intstring列表元祖字典

python之数据类型(数字与列表)

数字布尔值字符串列表

Python-字符串及列表操作-Day2

python之路数据类型

python-数据类型,元祖,列表,字典,文件操作篇