user1656238
user1656238

Reputation: 123

Convert binary to list of digits Python

I have the following scenario:

x = 0b0111

I would like to convert this value to:

y = [0, 1, 1, 1]

When I convert x = 0b1001, I can get y = [1, 0, 0, 1], but when I try to do the same for x = 0b0111, and then convert back with str(bin(y)) - I seem to lose the leading 0, and get 0b111.

Any suggestions?

Upvotes: 11

Views: 38860

Answers (11)

SixenseMan
SixenseMan

Reputation: 155

Here is a simple on-liner with no string parsing needed:

[x >> bin_idx & 1 for bin_idx in reversed(range(x.bit_length()))]

I believe it's a bit faster than other answers posted here.

Upvotes: 0

JFMoya
JFMoya

Reputation: 113

Updated for f-String:

x = 0b0111
y = [int(i) for i in f'{x:04b}']

y = [0, 1, 1, 1]

or:

x = 0b0111 # binary representation of int 7
n_bits = 4 # desired bits' len
y = [int(i) for i in f'{x:0{n_bits}b}']

Will populate a list of minimum len n-bits filling the list with leading 0's

Upvotes: 4

georg
georg

Reputation: 215049

For what it's worth, a pure arithmetic solution appears to be marginally faster:

import timeit

def bits1(n):
    b = []
    while n:
        b = [n & 1] + b
        n >>= 1
    return b or [0]

timeit.timeit(lambda: bits1(12345678))
[out] 7.717339038848877

def bits2(n):
    return [int(x) for x in bin(n)[2:]]


timeit.timeit(lambda: bits2(12345678))
[out] 10.297518014907837

2019 update: In python 3.7.3 the second version is slightly faster.

Upvotes: 5

Tom Hale
Tom Hale

Reputation: 47043

Given a number value and number of bits to represent it in width:

string = format(value, '0{}b'.format(width))
binary_list = [0 if c == '0' else 1 for c in string]

This is about one third faster than binary_list = [int(c) for c in string]

Upvotes: 0

Not very pythonian but:

byte = 0b00011001
arr = []
for i in range(7, -1, -1):
    arr.append((byte & 1<<i)>>i)
print(arr)

[0, 0, 0, 1, 1, 0, 0, 1]

this uses bitmasking to "extract" each bit and append to an array.

Upvotes: 0

noobar
noobar

Reputation: 838

If the length of bits is fixed to 4, there are two solutions:

[int(i) for i in '{0:04b}'.format(0b0111)]

or with NumPy,

import numpy as np
[int(i) for i in np.binary_repr(0b0111, 4)]

Upvotes: 2

raton
raton

Reputation: 428

c=[]
for i in bin(7)[2:]: 
        c.append(int(i)) #turning string "111", to 111
if len(c)==3:
    c.insert(0,0)
print(c)

# binary digit 7 produces '0b111' by this slicing[2:], result get '111'

so if element in list c is 3, 0 is inserted first.

Upvotes: 0

James Waldby - jwpat7
James Waldby - jwpat7

Reputation: 8711

An expression like map(int, list(bin((1<<8)+x))[-4:]) will give you the low 4 bits of a number, as a list. (Edit: A cleaner form is map(int,bin(x)[2:].zfill(4)) ; see below.) If you know how many bits you wish to show, replace the 4 (in [-4:]) with that number; and make the 8 (in (1<<8)) a larger number if necessary. For example:

>>> x=0b0111
>>> map(int,list(bin((1<<8)+x))[-4:])
[0, 1, 1, 1]
>>> x=37; map(int,list(bin((1<<8)+x))[-7:])
[0, 1, 0, 0, 1, 0, 1]
>>> [int(d) for d in bin((1<<8)+x)[-7:]]
[0, 1, 0, 0, 1, 0, 1]

The last example above shows an alternative to using map and list. The following examples show a slightly cleaner form for obtaining leading zeroes. In these forms, substitute the desired minimum number of bits in place of 8.

>>> x=37; [int(d) for d in bin(x)[2:].zfill(8)]
[0, 0, 1, 0, 0, 1, 0, 1]
>>> x=37; map(int,bin(x)[2:].zfill(8))
[0, 0, 1, 0, 0, 1, 0, 1]
>>> x=37; map(int,bin(x)[2:].zfill(5))
[1, 0, 0, 1, 0, 1]
>>> x=37; map(lambda k:(x>>-k)&1, range(-7,1))
[0, 0, 1, 0, 0, 1, 0, 1]

Upvotes: 3

iabdalkader
iabdalkader

Reputation: 17332

First convert the number to binary and then to string:

str(bin(7))
'0b111' #note the 0b in front of the binary number

Next, remove the 0b from the string

str(bin(7))[2:]
'111'

Finally we use list comprehension to create a list of ints from the string, which has roughly the following form:

[expr for i in iterable]
[int(i) for i in str(bin(x))[2:]]

Upvotes: 3

avasal
avasal

Reputation: 14872

check this simple way to do it... for this particular scenario

In [41]: x=0b0111

In [42]: l = [0,0,0,0]

In [43]: counter = -1

In [44]: for i in str(bin(x))[2:]:
   ....:     l[counter] = i
   ....:     counter = counter -1
   ....:

In [45]: l
Out[45]: [0, '1', '1', '1']

Upvotes: 0

Jordan Lewis
Jordan Lewis

Reputation: 17946

Once you get that string 0b111, it's straightforward to split out the digits that you're interested in. For each character of everything after the 0b in the string, convert it to an integer.

[int(d) for d in str(bin(x))[2:]]

Upvotes: 10

Related Questions