转换为二进制并保持前导零

Convert to binary and keep leading zeros

提问人:Niels Sønderbæk 提问时间:6/5/2013 最后编辑:martineauNiels Sønderbæk 更新时间:3/8/2023 访问量:285525

问:

我正在尝试使用 Python 中的 bin() 函数将整数转换为二进制。但是,它总是删除我实际需要的前导零,因此结果始终是 8 位:

例:

bin(1) -> 0b1

# What I would like:
bin(1) -> 0b00000001

有没有办法做到这一点?

Python 二进制 格式按 位运算符

评论

0赞 Martin Thoma 4/11/2016
参见:Python int to binary?,尤其是我对 n 位表示的回答。不完全相同,但我来到这个问题寻找我的答案......

答:

10赞 Peter Varo 6/5/2013 #1

您可以使用字符串格式化迷你语言(感谢 @Martijn Pieters 的建议)的想法:

def binary(num, length=8):
    return format(num, '#0{}b'.format(length + 2))

演示:

print(binary(1))

输出:

'0b00000001'

评论

2赞 Martijn Pieters 6/5/2013
可以使用相同的格式语言来包含前缀。用。还有 ,它使您不必执行完整的字符串模板。#format()
144赞 bwbrowning 6/5/2013 #2
>>> '{:08b}'.format(1)
'00000001'

请参见: 格式规范迷你语言


注意:对于 Python 2.6 或更早版本,您不能在 之前省略位置参数标识符,因此使用:

>>> '{0:08b}'.format(1)
'00000001'      

评论

3赞 Martijn Pieters 6/5/2013
这里没有必要使用什么时候会做。您缺少前缀。str.format()format()0b
2赞 Mark Ransom 6/5/2013
@MartijnPieters 更灵活,因为它允许您一次执行多个变量。我一直忘记这个函数甚至存在。诚然,在这种情况下,这是完全足够的。str.formatformat()format
1赞 Martijn Pieters 6/5/2013
@MarkRansom:确切地说,当你只使用一个元素,没有其他文本时,你没有使用字符串模板,你是在格式化一个值。在这种情况下,只需使用 .:-)str.format(){}format()
0赞 wheeler 3/10/2021
这不再起作用: print(“TCP: Option: Data: {:08b}”.format(option_data)) TypeError: unsupported format string passed to tuple.__format__
346赞 Martijn Pieters 6/5/2013 #3

使用 format() 函数

>>> format(14, '#010b')
'0b00001110'

该函数只是按照格式规范迷你语言对输入进行格式化。使格式包含前缀,大小格式化输出以适合 10 个字符的宽度,并带有填充;前缀为 2 个字符,另外 8 个字符为二进制数字。format()#0b01000b

这是最紧凑、最直接的选择。

如果要将结果放在较大的字符串中,请使用格式化的字符串文字 (3.6+) 或使用 str.format() 并将函数的第二个参数放在占位符的冒号之后:format(){:..}

>>> 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'

碰巧的是,即使只格式化单个值(因此不将结果放入更大的字符串中),使用格式化的字符串文字也比使用: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

但只有当紧密循环中的性能很重要时,我才会使用它,因为这样可以更好地传达意图。format(...)

如果您不想要前缀,只需删除并调整字段的长度:0b#

>>> format(14, '08b')
'00001110'

评论

5赞 kratostoical 12/17/2017
正是我想要的,这种格式对我非常有帮助。我已经开始学习位操作,我正在谷歌搜索 Python 中数字的位格式。找到了这个。谢谢。
0赞 voices 5/12/2019
效果很好。不过可能会有点笨重。format(192,'08b')+'.'+format(0,'08b')+'.'+format(2,'08b')+'.'+format(33,'08b') 11000000.00000000.00000010.00100001
0赞 Martijn Pieters 5/12/2019
@tjt263:这就是为什么我明确指出,如果您将结果放在更大的字符串中,请使用格式化的字符串文字 (3.6+) 或使用 str.format() 并将 format() 函数的第二个参数放在占位符 {:..} 的冒号之后:
2赞 Martijn Pieters 5/12/2019
@tjt263:例如使用。f"{192:08b}.{0:08b}.{2:08b}.{33:08b}"
0赞 voices 5/12/2019
很好。我从来不知道你的意思是单从解释。但现在我看到了你的例子,我可能永远不会忘记。干杯。
-1赞 Adam 4/1/2015 #4

你可以使用这样的东西

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

评论

2赞 β.εηοιτ.βε 4/1/2015
请至少为您的代码片段使用代码块。如果你真的希望它是一个很好的答案,那么还要添加一些关于为什么这个解决方案解决OP问题的评论。
0赞 Martijn Pieters 2/28/2020
您无需使用不同的字符串格式样式来添加可变宽度。只需添加另一个占位符:"{:0{l}b}".format(num, l=length)
47赞 rekinyz 12/11/2015 #5

我正在使用

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

将打印

'00000001'
-3赞 Anshul Garg 9/20/2016 #6

你可以使用 zfill:

print str(1).zfill(2) 
print str(10).zfill(2) 
print str(100).zfill(2)

指纹:

01
10
100

我喜欢这个解决方案,因为它不仅在输出数字时有帮助,而且在您需要将其分配给变量时也有帮助...... 例如:- x = str(datetime.date.today().month).zfill(2) 将在 2 月份返回 x 作为 '02'。

评论

1赞 Shaun 8/10/2017
Zfill 的问题在于它将二进制字符串视为字符串,并在二进制“b”指示符之前添加零......例如,给出 ' '0b1110' ' 并给出 ' '000b1110' ' 而不是 '0b00001110' ' 这是想要的bin(14)bin(14).zfill(8)
3赞 Mark 1/1/2017 #7

有时你只想要一个简单的一行:

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

蟒蛇 3

评论

2赞 Christoph Burschka 12/2/2017
请注意,不应该需要 - 接受生成器表达式。[ ]join()''.join('{0:08b}'.format(ord(x)) for x in input)
2赞 Martijn Pieters 2/28/2020
@ChristophBurschka请注意,由于需要进行两次传递,因此在加入之前,首先将生成器输入转换为列表。这会对性能造成一些影响,实际上在这里传递列表推导式而不是生成器表达式会更好。如果他们是规则的例外,那就是其中之一。str.join()
10赞 ruohola 1/9/2020 #8

使用 Python 时,您可以使用带有字符串格式的 f-strings>= 3.6

>>> var = 23
>>> f"{var:#010b}"
'0b00010111'

解释:

  • var要格式化的变量
  • :在此之后的所有内容都是格式说明符
  • #使用替代形式(添加前缀)0b
  • 0带零的焊盘
  • 10焊盘的总长度为 10(这包括 2 个字符0b)
  • b对数字使用二进制表示

评论

2赞 Martijn Pieters 2/28/2020
不,它不是最干净的,除非你对字符串做更多的事情,而不仅仅是一个占位符。否则,可以更好地传达意图。但是,这是最快的选择。但你已经知道了,对吧,因为我已经涵盖了你在我的回答中发布的所有内容format(var, "#010b")
1赞 ruohola 7/29/2022
我同意@MartijnPieters,如果您不需要它作为较长字符串的一部分,它会更干净。format
-3赞 Jaydeep Mahajan 5/31/2020 #9

您可以使用以下方法:string.rjust

string.rjust(length, fillchar)

fillchar是可选的

对于你的问题,你可以这样写

'0b'+ '1'.rjust(8,'0)

所以它将是“0b00000001”

评论

1赞 Thierry Lathuille 5/31/2020
存在语法错误。但更重要的是,它根本没有回答这个问题,即将 an 转换为其文本二进制表示;你甚至不以 .intint
6赞 Rustam A. 7/25/2021 #10

我喜欢python f-string格式,用于更复杂的事情,例如在format中使用参数:

>>> x = 5
>>> n = 8
>>> print(f"{x:0{n}b}")
00000101

在这里,我打印具有以下格式的变量:我希望它以(二进制)格式填充 to have length = 。有关详细信息,请参阅之前答案中的格式规范迷你语言。x0nb

0赞 Ioannis Tsampras 3/8/2023 #11

虽然到都发布了许多解决方案,但最快的方法(如果你不需要前面的“0b”部分)是将 f'{x:'b'}' 与 .zfill(n) 组合在一起进行填充

即使需要前导“0b”,也可以使用以下代码添加它:

'0b'+f'{i:b}'.zfill(n)

而且它仍然比使用该方法更快更具可读性f"{x:0{n}b}"

在此处查找相关的基准测试代码和结果