使用Python将二进制字符串转换为整数列表

AME*_*AME 5 python

我是Python的新手.这是我想要做的:

  1. 将长二进制字符串切成3位长的块.
  2. 将每个"块"存储到名为row的列表中.
  3. 将每个二进制块转换为数字(0-7).
  4. 将转换后的数字列表存储到名为numbers的新列表中.

这是我到目前为止:

def traverse(R):
        x = 0
        while x < (len(R) - 3):
            row = R[x] + R[x+1] + R[x+2]
            ???
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助!非常感谢.

Gre*_*ill 11

这样的事情应该这样做:

s = "110101001"
numbers = [int(s[i:i+3], 2) for i in range(0, len(s), 3)]
print numbers
Run Code Online (Sandbox Code Playgroud)

输出是:

[6, 5, 1]
Run Code Online (Sandbox Code Playgroud)

首先逐步打破这个问题:

>>> range(0, len(s), 3)
[0, 3, 6]
Run Code Online (Sandbox Code Playgroud)

range()函数在len(s)步骤3中生成一个0(小于最大值)的整数列表.

>>> [s[i:i+3] for i in range(0, len(s), 3)]
["110", "101", "001"]
Run Code Online (Sandbox Code Playgroud)

这是一个列表理解,s[i:i+3]用于评估i上述范围内的每一个.这s[i:i+3]是一个选择子字符串的切片.最后:

>>> [int(s[i:i+3], 2) for i in range(0, len(s), 3)]
[6, 5, 1]
Run Code Online (Sandbox Code Playgroud)

int(..., 2)函数从二进制(基数2,第二个参数)转换为整数.

请注意,上面的代码可能无法正确处理错误条件,例如长度不是3个字符的倍数的输入字符串.


Ale*_*lli 7

我假设"二进制字符串"实际上是指一个正常的字符串(即文本),其项目都是"0"或"1".

所以对于第1点和第2点,

row = [thestring[i:i+3] for i in xrange(0, len(thestring), 3)]
Run Code Online (Sandbox Code Playgroud)

当然,如果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
Run Code Online (Sandbox Code Playgroud)

所以第3点和第4点变为:

numbers = [aux[x] for x in row]
Run Code Online (Sandbox Code Playgroud)

这个字典查找应该比快速转换每个条目快得多.

编辑:有人建议我解释为什么我要aux为每个值输入两个条目x.关键是s可以是1到3个字符的任何长度,对于短的长度我想要两个条目 - 一个与s它一样(因为我提到的最后一个项目row可能短于3 ... ),并用它左边填充到3的长度0.

子表达式('00'+s)[-3:]通过将最后3个字符(即[-3:]切片部分)放在左边s(即'00'+s部分)的左边获得的字符串来计算"左边填充'0到3的长度" .如果s已经是3个字符长,那么整个子表达式将是相同的,s因此对该条目的赋值aux是无用的但是无害的,所以我发现更简单甚至不打扰检查(前置一个if len(s)<3:也没关系,味道问题;-).

还有其他的方法(例如x,如果需要再次格式化),但这不是代码的关键(它只执行8次来构建辅助"查找表",毕竟;-),所以我没有付出足够的代价注意.

...我也没有进行单元测试,所以它在一个不起眼的角落里有一个错误.你能看见它吗...?

假设row'01'作为最后一项:那把钥匙,我的代码头顶已建成后aux,将不会出现在aux(两者1001会,但这是很少的安慰;-).在上面的代码我使用原始的s,'1'和长度为三的填充版本'001',但中间长度 - 两个填充版本,oops,被忽略;-).

所以,这是一个正确的方法......:

aux = {}
for x in range(8):
  s = format(x, 'b')
  aux[s] = x
  while len(s) < 3:
    s = '0' + s
    aux[s] = x
Run Code Online (Sandbox Code Playgroud)

......无疑更简单,更明显,但更重要的是,正确;-).