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:二进制字符串的布尔列表的主要内容,如果未能解决你的问题,请参考以下文章