使用Python将二进制字符串转换为整数列表
我刚开始学Python。以下是我想做的事情:
- 把一个很长的二进制字符串切分成每组三位的块。
- 把每个“块”存储到一个叫做row的列表里。
- 把每个二进制块转换成一个数字(范围是0到7)。
- 把转换后的数字列表存储到一个新的列表叫做numbers里。
这是我目前的进展:
def traverse(R):
x = 0
while x < (len(R) - 3):
row = R[x] + R[x+1] + R[x+2]
???
谢谢你的帮助!我非常感激。
5 个回答
这样做不是更简单吗:
(我想要一个包含整数29的变量的高3位的数组)
先格式化你的变量和数组
a = ''
b = []
我从这个论坛的一个很好的例子中学来的,它把整数29格式化成5位二进制数,也就是从第0位到第4位,然后把这些位的字符串放到字符串变量"a"里。[编辑] 需要把格式从0:5b改成0:05b,这样当整数小于7时就能补零。
a = '{0:05b}'.format(29)
看看你的字符串变量
a
'11101'
把你的字符串分割成一个数组
b[0:3] = a[0:3]
这正是我想要的。
b
['1', '1', '1']
我假设你所说的“二进制字符串”其实是指一个普通的字符串(也就是文本),里面的内容全是‘0’或‘1’。
关于第1点和第2点,
row = [thestring[i:i+3] for i in xrange(0, len(thestring), 3)]
当然,如果len(thestring)
不是3的整倍数,最后的部分长度只会是1或2个字符,这是不可避免的;-).
对于第3点和第4点,我建议你建立一个辅助的临时字典来存储数据:
aux = {}
for x in range(8):
s = format(x, 'b')
aux[s] = x
aux[('00'+s)[-3:]] = x
这样第3点和第4点就变成了:
numbers = [aux[x] for x in row]
这个字典查找应该比每次动态转换每个条目要快得多。
编辑:有人建议我解释一下为什么我对每个x
的值在aux
中做了两个条目。原因是s
的长度可以是1到3个字符,对于短的长度我确实想要两个条目——一个是s
本身(因为我提到过row
中的最后一项可能短于3个字符...),另一个是用0
填充到3个字符的长度。
子表达式('00'+s)[-3:]
的作用是计算“用‘0’填充到3个字符长度的”,通过取字符串中最后3个字符(这就是[-3:]
切片的部分),而这个字符串是通过在s
前面加上‘00’得到的(这就是'00'+s
的部分)。如果s
已经是3个字符长,那么整个子表达式就等于s
,所以对aux
的这个条目的赋值是多余的,但也没什么坏处,因此我觉得不检查更简单(加上if len(s)<3:
也是可以的,这只是个人喜好;-)。
还有其他方法(比如在需要时再次格式化x
),但这并不是代码的关键部分(毕竟它只执行8次来构建辅助的“查找表”;-),所以我没有太关注这个。
...我也没有进行单元测试,所以在某个不明显的边缘情况下有个bug。你能发现吗...?
假设row
的最后一个条目是'01'
:在我上面的代码构建aux
后,那个键将不会出现在aux
中(1
和001
会存在,但这并不能让人感到安慰;-)。在上面的代码中,我使用了原始的s
,'1'
,以及填充到三位的版本'001'
,但中间的长度为2的填充版本,哎呀,被忽略了;-)。
所以,这里有一个正确的方法来做这件事...:
aux = {}
for x in range(8):
s = format(x, 'b')
aux[s] = x
while len(s) < 3:
s = '0' + s
aux[s] = x
...毫无疑问,这个方法更简单、更明显,但更重要的是,它是正确的;-).
像这样应该可以实现:
s = "110101001"
numbers = [int(s[i:i+3], 2) for i in range(0, len(s), 3)]
print numbers
输出结果是:
[6, 5, 1]
一步一步来分析,首先:
>>> range(0, len(s), 3)
[0, 3, 6]
range()
函数会生成一个从 0 开始,到小于最大值 len(s)
的整数列表,步长为 3。
>>> [s[i:i+3] for i in range(0, len(s), 3)]
["110", "101", "001"]
这是一个列表推导式,它会对上面范围内的每个 i
计算 s[i:i+3]
。这里的 s[i:i+3]
是一个切片,用来选择一个子字符串。最后:
>>> [int(s[i:i+3], 2) for i in range(0, len(s), 3)]
[6, 5, 1]
int(..., 2)
函数将二进制(基数为 2,第二个参数)转换为整数。
请注意,上面的代码可能无法正确处理一些错误情况,比如输入字符串的长度不是 3 的倍数。