在Python中将位列表转换为整数

2w3kk1z5  于 2023-01-16  发布在  Python
关注(0)|答案(7)|浏览(183)

我在Python中有这样的列表:[1,0,0,0,0,0,0,0]。我可以像输入0b10000000那样将其转换为整数吗(即转换为128)?我还需要将[1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0]这样的序列转换为整数(这里它将返回0b110000010000000,即259)。如果需要,列表的长度总是8的倍数。

7vhp5slm

7vhp5slm1#

您可以使用位移位:

out = 0
for bit in bitlist:
    out = (out << 1) | bit

这很容易击败A.R.S.提出的“int cast”方法,或者Steven Rumbalski提出的带有查找的修改后的cast:

>>> def intcaststr(bitlist):
...     return int("".join(str(i) for i in bitlist), 2)
... 
>>> def intcastlookup(bitlist):
...     return int(''.join('01'[i] for i in bitlist), 2)
... 
>>> def shifting(bitlist):
...     out = 0
...     for bit in bitlist:
...         out = (out << 1) | bit
...     return out
... 
>>> timeit.timeit('convert([1,0,0,0,0,0,0,0])', 'from __main__ import intcaststr as convert', number=100000)
0.5659139156341553
>>> timeit.timeit('convert([1,0,0,0,0,0,0,0])', 'from __main__ import intcastlookup as convert', number=100000)
0.4642159938812256
>>> timeit.timeit('convert([1,0,0,0,0,0,0,0])', 'from __main__ import shifting as convert', number=100000)
0.1406559944152832
vlf7wbxs

vlf7wbxs2#

...或使用位串模块

>>> from bitstring import BitArray
>>> bitlist=[1,0,0,0,0,0,0,0]
>>> b = BitArray(bitlist)
>>> b.uint
128
vltsax25

vltsax253#

我遇到了一个方法,略优于马丁皮特斯解决方案,虽然他的解决方案是漂亮的当然。我其实有点惊讶的结果,但无论如何...

import timeit

bit_list = [1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0]

def mult_and_add(bit_list):
    output = 0
    for bit in bit_list:
        output = output * 2 + bit
    return output

def shifting(bitlist):
     out = 0
     for bit in bitlist:
         out = (out << 1) | bit
     return out

n = 1000000

t1 = timeit.timeit('convert(bit_list)', 'from __main__ import mult_and_add as convert, bit_list', number=n)
print "mult and add method time is : {} ".format(t1)
t2 = timeit.timeit('convert(bit_list)', 'from __main__ import shifting as convert, bit_list', number=n)
print "shifting method time is : {} ".format(t2)

结果:

mult and add method time is : 1.69138722958 
shifting method time is : 1.94066818592
zzzyeukh

zzzyeukh4#

试试下面的一行代码:

int("".join(str(i) for i in my_list), 2)

如果你关心速度/效率,看看Martijn Pieters的解决方案。

3hvapo4f

3hvapo4f5#

不如这样:

out = sum([b<<i for i, b in enumerate(my_list)])

或按相反顺序:

out = sum([b<<i for i, b in enumerate(my_list[::-1])])
t5zmwmid

t5zmwmid6#

最快的一行程序:

def reduced_plus(bitlist):
    return functools.reduce(lambda acc, val: acc * 2 + val, bitlist)

基准:

import timeit
import functools

def shifting_plus(bitlist):
    out = 0
    for bit in bitlist:
        out = out * 2 + bit
    return out

def shifting(bitlist):
    out = 0
    for bit in bitlist:
        out = (out << 1) | bit
    return out

def reduced_plus(bitlist):
    return functools.reduce(lambda acc, val: acc * 2 + val, bitlist)

def reduced(bitlist):
    return functools.reduce(lambda acc, val: acc << 1 | val, bitlist)

def summed(bitlist):
    return sum([b<<i for i, b in enumerate(bitlist)])

def intcastlookup(bitlist):
    return int(''.join('01'[i] for i in bitlist), 2)

cycles = 1_000_000
for fname in ["shifting_plus", "shifting", "reduced_plus", "reduced", "summed", "intcastlookup"]:
    result = timeit.timeit('convert([1,0,0,0,0,0,0,0])', f'from __main__ import {fname} as convert')
    print(f"{result:.3f} s - {fname}")

结果:

0.465 s - shifting_plus
0.779 s - shifting
0.807 s - reduced_plus
0.841 s - summed
0.884 s - intcastlookup
1.024 s - reduced
ztmd8pv5

ztmd8pv57#

@Akavall建议的最简单的方法是最快的。下面mult_add_xor的额外计时显示了位操作在python中比较慢,因为简单的加法“+ bit”比xor“快。|比特”,并且乘以2比比特移位“〈〈1”快。

import timeit

bit_list = [1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]

def mult_and_add(bit_list):
    output = 0
    for bit in bit_list:
        output = output * 2 + bit
    return output

def mult_and_xor(bit_list):
    output = 0
    for bit in bit_list:
        output = output * 2 | bit
    return output

def shifting(bitlist):
    out = 0
    for bit in bitlist:
        out = (out << 1) | bit
    return out

n = 1000000

a1 = mult_and_add(bit_list)
a2 = mult_and_xor(bit_list)
a3 = shifting(bit_list)

print('a1: ', a1, ' a2: ', a2, ' a3: ', a3)
assert a1 == a2 == a3

t = timeit.timeit('convert(bit_list)',
                  'from __main__ import mult_and_add as convert, bit_list',
                  number=n)
print("mult and add method time is : {} ".format(t))
t = timeit.timeit('convert(bit_list)',
                  'from __main__ import mult_and_xor as convert, bit_list',
                  number=n)
print("mult and xor method time is : {} ".format(t))
t = timeit.timeit('convert(bit_list)',
                  'from __main__ import shifting as convert, bit_list',
                  number=n)
print("shifting method time is : {} ".format(t))

输出:

a1:  49280  a2:  49280  a3:  49280
mult and add method time is : 0.9469406669959426 
mult and xor method time is : 1.0905388034880161 
shifting method time is : 1.2844801126047969

相关问题