Convert to binary and keep leading zeros
Question:
I’m trying to convert an integer to binary using the bin() function in Python. However, it always removes the leading zeros, which I actually need, such that the result is always 8-bit:
Example:
bin(1) -> 0b1
# What I would like:
bin(1) -> 0b00000001
Is there a way of doing this?
Answers:
You can use the string formatting mini language (Thanks to @Martijn Pieters for the suggestion) idea:
def binary(num, length=8):
return format(num, '#0{}b'.format(length + 2))
Demo:
print(binary(1))
Output:
'0b00000001'
>>> '{:08b}'.format(1)
'00000001'
See: Format Specification Mini-Language
Note for Python 2.6 or older, you cannot omit the positional argument identifier before :
, so use
>>> '{0:08b}'.format(1)
'00000001'
Use the format()
function:
>>> format(14, '#010b')
'0b00001110'
The format()
function simply formats the input following the Format Specification mini language. The #
makes the format include the 0b
prefix, and the 010
size formats the output to fit in 10 characters width, with 0
padding; 2 characters for the 0b
prefix, the other 8 for the binary digits.
This is the most compact and direct option.
If you are putting the result in a larger string, use an formatted string literal (3.6+) or use str.format()
and put the second argument for the format()
function after the colon of the placeholder {:..}
:
>>> value = 14
>>> f'The produced output, in binary, is: {value:#010b}'
'The produced output, in binary, is: 0b00001110'
>>> 'The produced output, in binary, is: {:#010b}'.format(value)
'The produced output, in binary, is: 0b00001110'
As it happens, even for just formatting a single value (so without putting the result in a larger string), using a formatted string literal is faster than using format()
:
>>> import timeit
>>> timeit.timeit("f_(v, '#010b')", "v = 14; f_ = format") # use a local for performance
0.40298633499332936
>>> timeit.timeit("f'{v:#010b}'", "v = 14")
0.2850222919951193
But I’d use that only if performance in a tight loop matters, as format(...)
communicates the intent better.
If you did not want the 0b
prefix, simply drop the #
and adjust the length of the field:
>>> format(14, '08b')
'00001110'
You can use something like this
("{:0%db}"%length).format(num)
I am using
bin(1)[2:].zfill(8)
will print
'00000001'
You can use zfill:
print str(1).zfill(2)
print str(10).zfill(2)
print str(100).zfill(2)
prints:
01
10
100
I like this solution, as it helps not only when outputting the number, but when you need to assign it to a variable…
e.g. –
x = str(datetime.date.today().month).zfill(2) will return x as ’02’ for the month of feb.
Sometimes you just want a simple one liner:
binary = ''.join(['{0:08b}'.format(ord(x)) for x in input])
Python 3
When using Python >= 3.6
, you can use f-strings with string formatting:
>>> var = 23
>>> f"{var:#010b}"
'0b00010111'
Explanation:
var
the variable to format
:
everything after this is the format specifier
#
use the alternative form (adds the 0b
prefix)
0
pad with zeros
10
pad to a total length off 10 (this includes the 2 chars for 0b
)
b
use binary representation for the number
You can use string.rjust
method:
string.rjust(length, fillchar)
fillchar
is optional
and for your Question you can write like this
'0b'+ '1'.rjust(8,'0)
so it will be ‘0b00000001’
I like python f-string formatting for a little more complex things like using a parameter in format:
>>> x = 5
>>> n = 8
>>> print(f"{x:0{n}b}")
00000101
Here I print variable x
with following formatting: I want it to be left-filled with 0
to have length = n
, in b
(binary) format. See Format Specification Mini-Language from previous answers for more.
While many solutions have been posted here and there the fastest way (if you don’t need the ‘0b’ part in front) is combining f'{x:’b’}’ with .zfill(n) for padding.
Even if you want the leading ‘0b’ you can add it by using the following code:
'0b'+f'{i:b}'.zfill(n)
And it is still faster and more readable than using the f"{x:0{n}b}"
method
Find relevant benchmarking code and results here
I’m trying to convert an integer to binary using the bin() function in Python. However, it always removes the leading zeros, which I actually need, such that the result is always 8-bit:
Example:
bin(1) -> 0b1
# What I would like:
bin(1) -> 0b00000001
Is there a way of doing this?
You can use the string formatting mini language (Thanks to @Martijn Pieters for the suggestion) idea:
def binary(num, length=8):
return format(num, '#0{}b'.format(length + 2))
Demo:
print(binary(1))
Output:
'0b00000001'
>>> '{:08b}'.format(1)
'00000001'
See: Format Specification Mini-Language
Note for Python 2.6 or older, you cannot omit the positional argument identifier before :
, so use
>>> '{0:08b}'.format(1)
'00000001'
Use the format()
function:
>>> format(14, '#010b')
'0b00001110'
The format()
function simply formats the input following the Format Specification mini language. The #
makes the format include the 0b
prefix, and the 010
size formats the output to fit in 10 characters width, with 0
padding; 2 characters for the 0b
prefix, the other 8 for the binary digits.
This is the most compact and direct option.
If you are putting the result in a larger string, use an formatted string literal (3.6+) or use str.format()
and put the second argument for the format()
function after the colon of the placeholder {:..}
:
>>> value = 14
>>> f'The produced output, in binary, is: {value:#010b}'
'The produced output, in binary, is: 0b00001110'
>>> 'The produced output, in binary, is: {:#010b}'.format(value)
'The produced output, in binary, is: 0b00001110'
As it happens, even for just formatting a single value (so without putting the result in a larger string), using a formatted string literal is faster than using format()
:
>>> import timeit
>>> timeit.timeit("f_(v, '#010b')", "v = 14; f_ = format") # use a local for performance
0.40298633499332936
>>> timeit.timeit("f'{v:#010b}'", "v = 14")
0.2850222919951193
But I’d use that only if performance in a tight loop matters, as format(...)
communicates the intent better.
If you did not want the 0b
prefix, simply drop the #
and adjust the length of the field:
>>> format(14, '08b')
'00001110'
You can use something like this
("{:0%db}"%length).format(num)
I am using
bin(1)[2:].zfill(8)
will print
'00000001'
You can use zfill:
print str(1).zfill(2)
print str(10).zfill(2)
print str(100).zfill(2)
prints:
01
10
100
I like this solution, as it helps not only when outputting the number, but when you need to assign it to a variable…
e.g. –
x = str(datetime.date.today().month).zfill(2) will return x as ’02’ for the month of feb.
Sometimes you just want a simple one liner:
binary = ''.join(['{0:08b}'.format(ord(x)) for x in input])
Python 3
When using Python >= 3.6
, you can use f-strings with string formatting:
>>> var = 23
>>> f"{var:#010b}"
'0b00010111'
Explanation:
var
the variable to format:
everything after this is the format specifier#
use the alternative form (adds the0b
prefix)0
pad with zeros10
pad to a total length off 10 (this includes the 2 chars for0b
)b
use binary representation for the number
You can use string.rjust
method:
string.rjust(length, fillchar)
fillchar
is optional
and for your Question you can write like this
'0b'+ '1'.rjust(8,'0)
so it will be ‘0b00000001’
I like python f-string formatting for a little more complex things like using a parameter in format:
>>> x = 5
>>> n = 8
>>> print(f"{x:0{n}b}")
00000101
Here I print variable x
with following formatting: I want it to be left-filled with 0
to have length = n
, in b
(binary) format. See Format Specification Mini-Language from previous answers for more.
While many solutions have been posted here and there the fastest way (if you don’t need the ‘0b’ part in front) is combining f'{x:’b’}’ with .zfill(n) for padding.
Even if you want the leading ‘0b’ you can add it by using the following code:
'0b'+f'{i:b}'.zfill(n)
And it is still faster and more readable than using the f"{x:0{n}b}"
method
Find relevant benchmarking code and results here