I have such list in Python: [1,0,0,0,0,0,0,0]
. Can I convert it to integer like as I've typed 0b10000000 (i.e. convert to 128)?
I need also to convert sequences like [1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0]
to integers (here it will return 0b1100000010000000, i.e. 259).
Length of list is always a multiple of 8, if it is necessary.

- 57,944
- 17
- 167
- 143

- 3,285
- 5
- 30
- 44
-
This might help you: http://stackoverflow.com/questions/2576712/using-python-how-can-i-read-the-bits-in-a-byte – Markus Unterwaditzer Sep 17 '12 at 14:26
-
Where are these lists coming from? Are they originally character input? – Steven Rumbalski Sep 17 '12 at 14:32
-
1They are calculated from integers. If you want I can post code here. – ghostmansd Sep 17 '12 at 14:35
-
@ghostmansd: I just wanted to make sure they weren't originally characters. That would have changed which answer was fastest. – Steven Rumbalski Sep 17 '12 at 14:40
-
@ghostmansd: What is the average length of your bitlist? At 64 bits the string version performs the best (on my computer). – Steven Rumbalski Sep 17 '12 at 15:11
-
@StevenRumbalski: the `intcastlookup` method starts to approach bitshifting by 16 bytes on mine. – Martijn Pieters Sep 17 '12 at 15:15
-
@StevenRumbalski: they appear from bytes using `array.array('B', sequence)`. – ghostmansd Sep 17 '12 at 17:49
7 Answers
You can use bitshifting:
out = 0
for bit in bitlist:
out = (out << 1) | bit
This easily beats the "int cast" method proposed by A. R. S., or the modified cast with lookup proposed by Steven Rumbalski:
>>> 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

- 1,048,767
- 296
- 4,058
- 3,343
-
BTW, could you suggest the way to convert integer from 0b10000000 to 0b000001 without having to create list of bits? – ghostmansd Sep 17 '12 at 14:33
-
3@ghostmansd: Use `.format()` string formatting: `'0b{0:08b}'.format(integer)` will format an integer to a 0-padded 8-character string with leading `0b`. – Martijn Pieters Sep 17 '12 at 14:39
-
Yea that "int cast" method is what immediately sprung to my mind (seemed like a nice clean solution if you aren't too concerned with efficiency). But yes, this is clearly faster. – arshajii Sep 17 '12 at 14:39
-
Here's a much faster string version: `int(''.join('01'[i] for i in bitlist), 2)`. Still not as fast as bitshifting. – Steven Rumbalski Sep 17 '12 at 14:44
-
-
FWIW, my timings on 2.7 on Windows 7: 0.493230227672, 0.292227349768, 0.14324616472. – Steven Rumbalski Sep 17 '12 at 14:48
-
@StevenRumbalski: mine were measured on 2.7 on Mac OS X 10.7.4. – Martijn Pieters Sep 17 '12 at 14:49
-
`reduce(lambda a,b: a<<1 | b, [1,0,0,0,0,0,0,0], 0)` is the functional way to do it. `timeit` shows that it's slower than `shifting` though. Numbers on my computer: 0.141 for reduce, 0.08 for shifting. – Alfe Sep 17 '12 at 14:53
-
Interesting. If I use `out = out * 2 + bit` instead of `out = (out << 1) | bit`, it is _slightly_ faster (~1.4s instead of ~1.5s). (EDIT: for longer bitlists, 2.0s instead of 2.2s. Although it does vary wildly, so it might just be noise.) – Jasmijn Sep 17 '12 at 15:12
-
@MartijnPieters. I deleted the comment because I implemented the test incorrectly. I did find that the `intcastlookup` starts to perform better at 64 bits on my computer. – Steven Rumbalski Sep 17 '12 at 15:14
-
Is there a reason why a left bit shift of a positive number would give a negative number in Python3.9? e.g. `(4885555926706653251 << 1) | 0` is sometimes returning `-8675632220296245114` but should return `9771111853413306502`. This issue is only reproducible in the context of a loop like under `shifting` in the answer above – jay-tyler Mar 24 '22 at 06:55
-
@jay-tyler are you sure the values are python int objects? Make sure they are not, say, numpy `int64` integers, which have a fixed size and do exactly what you observed. I can reproduce this with `import numpy as np` and `np.int64(4885555926706653251) << 1`. – Martijn Pieters Mar 24 '22 at 23:12
-
@MartijnPieters Yes, I think you're right, thank you. Was dealing with a series of `numpy.int64` coming from an external call. `numpy.int64` has somewhat misleading repr and str implementations. – jay-tyler Apr 05 '22 at 23:13
...or using the bitstring module
>>> from bitstring import BitArray
>>> bitlist=[1,0,0,0,0,0,0,0]
>>> b = BitArray(bitlist)
>>> b.uint
128

- 44,604
- 7
- 83
- 130
-
I could use `bitstring` or `bitarray` modules before, but this time I can't. I need a solution which doesn't require additional packages. Thanks, however! – ghostmansd Sep 17 '12 at 14:35
-
2you didn't state that in the question, so I thought I'd add a bitstring-solution as an alternative to Martijns excellent answer :-) – Fredrik Pihl Sep 17 '12 at 14:41
I came across a method that slightly outperforms Martijn Pieters solution, though his solution is prettier of course. I am actually a bit surprised by the results, but anyway...
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)
Result:
mult and add method time is : 1.69138722958
shifting method time is : 1.94066818592

- 82,592
- 51
- 207
- 251
-
Slightly surprising result, yes. I'd guess that multiplication by two is _exactly_ the same as shifting by one, but it could be due to that an OR operation is slower than a XOR operation. Addition can be simplified to XOR in your case since you won't have a carry, because of the bit shift. – Zut Nov 02 '13 at 22:48
-
It would be very interesting to know why this could possibly be. Obviously at the processor hardware level, the shifting pattern is certainly correct and well known for decades. However possible special code optimizations which are not apply to shifting, and are to multiplication and addition, which allow the processors pre-execution and branching prediction to work better, or it unrolls the loop or does something. There is an explanation and in part it means python's bitwise operation support of or and shifting is not very good. – Gregory Morse Jul 12 '20 at 16:58
-
Oh so by the way in Python 3.7.7, this is still true... ```Python 3.7.7 (default, Mar 23 2020, 23:19:08) [MSC v.1916 64 bit (AMD64)] IPython 7.13.0 -- An enhanced Interactive Python. %timeit mult_and_add(bit_list) 957 ns ± 3.76 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) %timeit shifting(bit_list) 1.33 µs ± 11.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)``` – Gregory Morse Jul 12 '20 at 17:03
Try this one-liner:
int("".join(str(i) for i in my_list), 2)
If you're concerned with speed/efficiency, take a look at Martijn Pieters' solution.

- 127,459
- 24
- 238
- 287
-
Here's a much faster string version: `int(''.join('01'[i] for i in bitlist), 2)`. Still not as fast as bitshifting. – Steven Rumbalski Sep 17 '12 at 14:39
-
@ghostmansd. At 64 bits the string version starts to perform faster (on my computer). – Steven Rumbalski Sep 17 '12 at 15:12
how about this:
out = sum([b<<i for i, b in enumerate(my_list)])
or in reverse order:
out = sum([b<<i for i, b in enumerate(my_list[::-1])])

- 41
- 1
Fastest one-liner:
def reduced_plus(bitlist):
return functools.reduce(lambda acc, val: acc * 2 + val, bitlist)
Benchmarking:
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}")
results:
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

- 4,674
- 2
- 26
- 20
The simplest method suggested by @Akavall is the fastest one. The additional timing below for mult_add_xor shows that the bit operations are slower in python since simple addition "+ bit" is faster than xor "| bit" and the multiplication by 2 is faster than the bit shift "<< 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))
Output:
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

- 1,108
- 13
- 19