[英]Convert binary to list of digits Python
我有以下场景:
x = 0b0111
我想将此值转换为:
y = [0, 1, 1, 1]
当我转换x = 0b1001
,我可以得到y = [1, 0, 0, 1]
,但是当我尝试为x = 0b0111
做同样的x = 0b0111
,然后用str(bin(y))
转换回来时 - 我似乎失去领先的0
,并获得0b111
。
有什么建议?
一旦获得字符串0b111
,就可以直接拆分出您感兴趣的数字。对于字符串中0b
之后的所有字符的每个字符,将其转换为整数。
[int(d) for d in str(bin(x))[2:]]
就其价值而言,纯算术解决方案似乎略快:
import timeit
def bits1(n):
b = []
while n:
b = [n & 1] + b
n >>= 1
return b or [0]
timeit.timeit(lambda: bits1(12345678))
[out] 7.717339038848877
def bits2(n):
return [int(x) for x in bin(n)[2:]]
timeit.timeit(lambda: bits2(12345678))
[out] 10.297518014907837
2019 更新:在 python 3.7.3 中,第二个版本稍微快一些。
首先将数字转换为二进制,然后再转换为字符串:
str(bin(7))
'0b111' #note the 0b in front of the binary number
接下来,从字符串中删除0b
str(bin(7))[2:]
'111'
最后,我们使用列表推导从字符串中创建一个整数列表,其形式大致如下:
[expr for i in iterable]
[int(i) for i in str(bin(x))[2:]]
像map(int, list(bin((1<<8)+x))[-4:])
这样的表达式会给你一个数字的低 4 位,作为一个列表。 (编辑:更map(int,bin(x)[2:].zfill(4))
形式是map(int,bin(x)[2:].zfill(4))
;见下文。)如果您知道要显示多少位,请替换 4(在[-4:]
) 与那个号码; 并在必要时使 8 (in (1<<8)
) 成为更大的数字。 例如:
>>> x=0b0111
>>> map(int,list(bin((1<<8)+x))[-4:])
[0, 1, 1, 1]
>>> x=37; map(int,list(bin((1<<8)+x))[-7:])
[0, 1, 0, 0, 1, 0, 1]
>>> [int(d) for d in bin((1<<8)+x)[-7:]]
[0, 1, 0, 0, 1, 0, 1]
上面的最后一个示例显示了使用 map 和 list 的替代方法。 以下示例显示了一种用于获取前导零的更简洁的形式。 在这些形式中,用所需的最小位数代替 8。
>>> x=37; [int(d) for d in bin(x)[2:].zfill(8)]
[0, 0, 1, 0, 0, 1, 0, 1]
>>> x=37; map(int,bin(x)[2:].zfill(8))
[0, 0, 1, 0, 0, 1, 0, 1]
>>> x=37; map(int,bin(x)[2:].zfill(5))
[1, 0, 0, 1, 0, 1]
>>> x=37; map(lambda k:(x>>-k)&1, range(-7,1))
[0, 0, 1, 0, 0, 1, 0, 1]
如果比特长度固定为4
,有两种解决方案:
[int(i) for i in '{0:04b}'.format(0b0111)]
或使用 NumPy,
import numpy as np
[int(i) for i in np.binary_repr(0b0111, 4)]
检查这个简单的方法来做到这一点......对于这个特定的场景
In [41]: x=0b0111
In [42]: l = [0,0,0,0]
In [43]: counter = -1
In [44]: for i in str(bin(x))[2:]:
....: l[counter] = i
....: counter = counter -1
....:
In [45]: l
Out[45]: [0, '1', '1', '1']
c=[]
for i in bin(7)[2:]:
c.append(int(i)) #turning string "111", to 111
if len(c)==3:
c.insert(0,0)
print(c)
# binary digit 7 produces '0b111' by this slicing[2:], result get '111'
因此,如果列表 c 中的元素为 3,则首先插入 0。
不是很pythonian但是:
byte = 0b00011001
arr = []
for i in range(7, -1, -1):
arr.append((byte & 1<<i)>>i)
print(arr)
[0, 0, 0, 1, 1, 0, 0, 1]
这使用位掩码来“提取”每一位并附加到数组中。
给定一个value
和位数来表示它的width
:
string = format(value, '0{}b'.format(width))
binary_list = [0 if c == '0' else 1 for c in string]
这比binary_list = [int(c) for c in string]
快三分之一
为 f-String 更新:
x = 0b0111
y = [int(i) for i in f'{x:04b}']
y = [0, 1, 1, 1]
要么:
x = 0b0111 # binary representation of int 7
n_bits = 4 # desired bits' len
y = [int(i) for i in f'{x:0{n_bits}b}']
将填充最小 len n 位的列表,用前导 0 填充列表
这是一个不需要字符串解析的简单在线:
[x >> bin_idx & 1 for bin_idx in reversed(range(math.ceil(math.log(x, 2))))]
我相信它比这里发布的其他答案要快一些。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.