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

时间:2009-09-06 21:46:52

标签: python

我是Python新手。这就是我想要做的事情:

  1. 将长二进制字符串切成3个数字长的块。
  2. 将每个“块”存储到名为row的列表中。
  3. 将每个二进制块转换为数字(0-7)。
  4. 将转换后的数字列表存储到名为numbers的新列表中。
  5. 这是我到目前为止所做的:

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

    感谢您的帮助!非常感谢。

5 个答案:

答案 0 :(得分:11)

这样的事情应该这样做:

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()函数在步骤3中生成0的整数列表,小于最大len(s)

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

这是一个list comprehension,用于评估上述范围内每个s[i:i+3]的{​​{1}}。 islice,用于选择子字符串。最后:

s[i:i+3]

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

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

答案 1 :(得分:7)

我假设“二进制字符串”实际上是指一个普通的字符串(即文本),其项目都是“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]

这个dict查找应该比在运行中转换每个条目快得多。

修改:有人建议我解释为什么我为aux的每个值在x中输入两个条目。关键是s可以是1到3个字符的任意长度,对于短的长度,我确实需要两个条目 - 一个与s一样(因为我提到了最后一个项目)在row中可能短于3 ...),并且使用0 s将其填充到3的长度。

子表达式('00'+s)[-3:]通过放置通过放置获得的字符串的最后3个字符(即[-3:]切片部分)来计算“左边填充'0到3的长度” s左侧的零(即'00'+s部分)。如果s已经有3个字符长,则整个子表达式将等于s,因此对aux条目的赋值无用但无害,所以我发现更简单甚至不打扰检查(预先加if len(s)<3:也没关系,味道问题; - )。

还有其他方法(例如,如果需要再次格式化x),但这不是代码的关键(它只执行8次来构建辅助“查找表”,毕竟;-),所以我没有给予足够的重视。

...我也没有对它进行单元测试,所以它在一个不起眼的角落案例中有一个错误。你能看到它吗??

假设row'01'作为最后一个条目:在我的代码上面构建aux之后,该密钥将不会出现在aux中({{1}将来,1,但这是一个很少的安慰;-)。在上面的代码中,我使用原始001s和长度为3的填充版本'1',但中间长度 - 两个填充版本,oops,被忽略了;-)

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

'001'

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

答案 2 :(得分:1)

如果您正在处理任何类型的原始数据,我想推荐一下优秀的bitstring模块:

>>> import bitstring
>>> bits = bitstring.Bits('0b110101001')
>>> [b.uint for b in bits.cut(3)]
[6, 5, 1]

home page的说明:

  

一个Python模块,用于创建,操作和分析   二进制数据尽可能简单自然。

     

Bitstrings可以用整数,浮点数,十六进制,八进制构造,   二进制,字节或文件。它们也可以使用创建和解释   灵活的格式字符串。

     

可以切割,连接,反转,插入,   用简单的方法或使用切片表示法覆盖等。他们   也可以读取,搜索和替换,以及导航,   类似于文件或流。

     

在内部,位数据有效地存储在字节数组中   模块已针对速度进行了优化,并且具有出色的代码覆盖率   超过400次单元测试。

答案 3 :(得分:0)

Greg和Alex的精彩回答!列表理解和切片是如此pythonic! 对于短输入字符串,我不打扰字典查找技巧,但如果输入字符串更长,我会,以及使用gen-exps而不是list-comps,即:

row = list(thestring [i:i + 3] for x in xrange(0,len(thestring),3))

numbers = list(行中x的aux [x])

因为gen-exp表现更好。

答案 4 :(得分:0)

这不会更容易:

(我想要一个包含整数29的变量的高3位数组)

首先格式化变量和数组

a =''

b = []

我从这个论坛的一个非常好的例子中偷走了这个,它将整数29格式化为5位,从0到4位,并将位串放入字符串变量“a”。 [编辑]需要将格式从0:5b更改为0:05b,以便在整数<1时填充零。 7。

a ='{0:05b}'。format(29)

查看你的字符串变量

'11101'

将您的字符串拆分为数组

b [0:3] = a [0:3]

这正是我想要的。

B'/ P>

['1','1','1']