Search code examples
pythonpython-3.xbinaryf-string

How to print binary numbers using f"" string instead of .format()?


For printing some numbers to their binary formats, we simply use the .format() method, like so:

# Binary
for i in range(5+1):
    print("{0:>2} in binary is {0:>08b}".format(i))

Output:

0 in binary is 00000000
1 in binary is 00000001
2 in binary is 00000010
3 in binary is 00000011
4 in binary is 00000100
5 in binary is 00000101

Similar is for printing in other formats (hex and octal) which just requires replacing the latter braces to the digits we want to print. But is there a way to use the new f"" string to replace the .format() command? I know this might seem trivial but I stumped over this while playing around with the new feature, besides f"" makes the code shorter and more readable.

for i in range(5+1):
    print(f'{0:>2} in binary is {0:>08b}')
# This prints out just 0s

Solution

  • Your f-string should have expressions in it rather than indices:

    f'{i:>2} in binary is {i:>08b}'
    

    Anywhere you had 0 in the original format string should be replaced by the actual first argument: in this case i.

    Caveat

    The expression in the f-string is evaluated twice, but the argument to format is only evaluated once when you access it by index. This matters for more complicated expressions. For example:

    "{0:>2} in binary is {0:>08b}".format(i + 10)
    

    Here the addition i + 10 only happens once. On the other hand

    f"{i+10:>2} in binary is {i+10:>08b}"
    

    does the addition twice because it is equivalent to

    "{:>2} in binary is {:>08b}".format(i + 10, i + 10)
    

    Or

    "{0:>2} in binary is {1:>08b}".format(i + 10, i + 10)
    

    The workaround is to pre-compute the results of expressions that appear in your f-string more than once:

    j = i + 10
    f"{j:>2} in binary is {j:>08b}"
    

    Now j is evaluated multiple times, but it's just a simple reference.