253

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?

1
  • See also: Python int to binary?, especially my answer with the n-bit representation. Not exactly the same, but I came to this question searching my answer... Commented Apr 10, 2016 at 20:20

11 Answers 11

366

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'
Sign up to request clarification or add additional context in comments.

7 Comments

Exactly what I was looking for, this formatting is really helpful to me. I have started learning bit manipulation and I was googling for bit formatting for numbers in Python. Found this. Thank you.
Works nice. Can get a bit bulky though. format(192,'08b')+'.'+format(0,'08b')+'.'+format(2,'08b')+'.'+format(33,'08b') 11000000.00000000.00000010.00100001
@tjt263: That's why I explicitly state that 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 {:..}:
@tjt263: e.g. use f"{192:08b}.{0:08b}.{2:08b}.{33:08b}".
Very nice. I never would have known that's what you meant from explanation alone. But now I've seen your example, I'll probably never forget it. Cheers.
|
151
>>> '{: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'      

4 Comments

There is no need to use str.format() here when format() will do. You are missing the 0b prefix.
@MartijnPieters, str.format is more flexible than format() because it will allow you to do multiple variables at once. I keep forgetting that the format function even exists. Admittedly it's perfectly adequate in this case.
@MarkRansom: Exactly, when you are only using str.format() with just one {} element, no other text, you are not using string templating, you are formatting one value. In that case just use format(). :-)
This does not work anymore: print("TCP: Option: Data: {:08b}".format(option_data)) TypeError: unsupported format string passed to tuple.__format__
55

I am using

bin(1)[2:].zfill(8)

will print

'00000001'

Comments

13

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

2 Comments

No, it is not the cleanest, not unless you do more with the string than just a single placeholder. Otherwise format(var, "#010b") communicates intent much better. It is, however, the fastest option. But you know that already, right, because I already cover all of what you posted in my answer.
I agree @MartijnPieters, format is cleaner if you don't need it as part of a longer string.
10

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.

Comments

10

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'

1 Comment

The same formatting language can be used to include the prefix for you. Use #. There is also format(), which saves you having to do a full string template.
3

Sometimes you just want a simple one liner:

binary = ''.join(['{0:08b}'.format(ord(x)) for x in input])

Python 3

2 Comments

Note that the [ ] shouldn't be needed - join() accepts a generator expression. ''.join('{0:08b}'.format(ord(x)) for x in input)
@ChristophBurschka note that because str.join() needs to make two passes, a generator input is first converted to a list before joining. This takes a bit of a toll on performance and do it’s actually better here to pass in a list comprehension rather than a generator expression. It’s one if them exceptions to the rule.
0

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

Comments

-1

You can use something like this

("{:0%db}"%length).format(num)

2 Comments

Please at least use code block for your code snippet. And if you really want it to be a good answer, then also add some comments on why this solution is solving OP question.
You don’t need to use a different string formatting style just to add a variable width. Just add another placeholder: "{:0{l}b}".format(num, l=length)
-3

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.

1 Comment

problem with zfill is it treats the binary string like a string and adds the zeros before the binary 'b' indicator... eg bin(14) gives ` '0b1110' ` and bin(14).zfill(8) gives ` '000b1110' ` not ` '0b00001110' ` which is whats desired
-3

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'

1 Comment

There is a syntax error. But more importantly, it doesn't answer the question at all, which is about converting an int to its textual binary representation; you don't even start with an int.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.