转换为二进制并保留前导零
Posted
技术标签:
【中文标题】转换为二进制并保留前导零【英文标题】:Convert to binary and keep leading zeros 【发布时间】:2013-05-31 08:07:51 【问题描述】:我正在尝试使用 Python 中的 bin() 函数将整数转换为二进制。但是,它总是会删除我实际需要的前导零,这样结果总是 8 位:
例子:
bin(1) -> 0b1
# What I would like:
bin(1) -> 0b00000001
有没有办法做到这一点?
【问题讨论】:
另见:Python int to binary?,尤其是具有 n 位表示的my answer。不完全一样,但我来这个问题是为了寻找我的答案...... 【参考方案1】:使用format()
function:
>>> format(14, '#010b')
'0b00001110'
format()
函数只是格式化Format Specification mini language 之后的输入。 #
使格式包含 0b
前缀,010
大小格式化输出以适应 10 个字符的宽度,并带有 0
填充; 0b
前缀的 2 个字符,其他 8 个二进制数字。
这是最简洁直接的选择。
如果您要将结果放在更大的字符串中,请使用formatted string literal (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'
【讨论】:
正是我想要的,这种格式对我真的很有帮助。我已经开始学习位操作,并且正在谷歌上搜索 Python 中数字的位格式。找到了这个。谢谢。 效果很好。虽然可以变得有点笨重。format(192,'08b')+'.'+format(0,'08b')+'.'+format(2,'08b')+'.'+format(33,'08b')
11000000.00000000.00000010.00100001
@tjt263:这就是为什么我明确指出 如果您将结果放在更大的字符串中,请使用格式化的字符串文字(3.6+)或使用 str.format()
并放入第二个参数对于占位符:..
的冒号后的format()函数:
@tjt263:例如使用f"192:08b.0:08b.2:08b.33:08b"
。
非常好。我永远不会知道这就是您仅从解释中的意思。但是现在我看到了你的例子,我可能永远不会忘记它。干杯。【参考方案2】:
>>> ':08b'.format(1)
'00000001'
见:Format Specification Mini-Language
注意对于 Python 2.6 或更早版本,您不能省略 :
之前的位置参数标识符,因此请使用
>>> '0:08b'.format(1)
'00000001'
【讨论】:
这里没有必要使用str.format()
format()
可以。您缺少 0b
前缀。
@MartijnPieters,str.format
比format()
更灵活,因为它允许您一次执行多个变量。我一直忘记format
函数甚至存在。诚然,在这种情况下它是完全足够的。
@MarkRansom:确切地说,当您仅使用 str.format()
和一个
元素,没有其他文本时,您不使用字符串模板,您正在格式化一个值。在这种情况下,只需使用format()
。 :-)
这不再起作用:print("TCP: Option: Data: :08b".format(option_data)) TypeError: unsupported format string passing to tuple.__format__【参考方案3】:
我正在使用
bin(1)[2:].zfill(8)
将打印
'00000001'
【讨论】:
【参考方案4】:您可以使用字符串格式化迷你语言:
def binary(num, pre='0b', length=8, spacer=0):
return '0:1>2'.format(pre, spacer, length).format(bin(num)[2:])
演示:
print binary(1)
输出:
'0b00000001'
编辑: 基于@Martijn Pieters 的想法
def binary(num, length=8):
return format(num, '#0b'.format(length + 2))
【讨论】:
可以使用相同的格式语言为您包含前缀。使用#
。还有format()
,这样就不用做一个完整的字符串模板了。【参考方案5】:
使用 Python >= 3.6
时,最简洁的方法是使用 f-strings 和 string formatting:
>>> var = 23
>>> f"var:#010b"
'0b00010111'
解释:
var
要格式化的变量
:
后面的都是格式说明符
#
使用替代形式(添加 0b
前缀)
0
用零填充
10
填充到总长度为 10(这包括 0b
的 2 个字符)
b
使用二进制表示数字
【讨论】:
不,它不是最干净的,除非你对字符串做更多而不是一个占位符。否则format(var, "#010b")
会更好地传达intent。但是,它是最快的选择。但是您已经知道了,对,因为我已经在我的回答中涵盖了您发布的所有内容。【参考方案6】:
有时您只需要一个简单的衬里:
binary = ''.join(['0:08b'.format(ord(x)) for x in input])
Python 3
【讨论】:
请注意,[ ]
不应该是必需的 - join()
接受生成器表达式。 ''.join('0:08b'.format(ord(x)) for x in input)
@ChristophBurschka 请注意,因为str.join()
需要进行两次传递,所以在加入之前首先将生成器输入转换为列表。这会对性能产生一些影响,实际上这里 更好 传递列表推导而不是生成器表达式。如果他们是规则的例外,那就是其中之一。【参考方案7】:
我喜欢用 python f-string 格式化一些更复杂的东西,比如在格式中使用参数:
>>> x = 5
>>> n = 8
>>> print(f"x:0nb")
00000101
在这里,我使用以下格式打印变量 x
:我希望它以 b
(二进制)格式左填充 0
以具有长度 = n
。有关更多信息,请参阅先前答案中的 Format Specification Mini-Language。
【讨论】:
【参考方案8】:你可以使用这样的东西
(":0%db"%length).format(num)
【讨论】:
请至少为您的代码 sn-p 使用代码块。如果你真的希望它是一个好的答案,那么还要添加一些关于为什么这个解决方案正在解决 OP 问题的 cmets。 您不需要使用不同的字符串格式样式来添加可变宽度。只需添加另一个占位符:":0lb".format(num, l=length)
【参考方案9】:
你可以使用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) 将返回 x 为 2 月份的“02”。
【讨论】:
zfill 的问题是将二进制字符串视为字符串并在二进制 'b' 指示符之前添加零...例如,bin(14)
给出 ` '0b1110' ` 和 bin(14).zfill(8)
给出 ` '000b1110' ` 不是 ` '0b00001110' ` 这是想要的【参考方案10】:
你可以使用python的rjust字符串方法 句法: string.rjust(长度,填充字符) fillchar 是可选的
对于你的问题,你可以这样写
'0b'+ '1'.rjust(8,'0)
所以它将是'0b00000001'
【讨论】:
存在语法错误。但更重要的是,它根本没有回答关于将int
转换为其文本二进制表示的问题;你甚至不以 int
开头。以上是关于转换为二进制并保留前导零的主要内容,如果未能解决你的问题,请参考以下文章
在 Rust 中将二进制字符串转换为带有前导零的十六进制字符串
在 Java 中,如何将字节数组转换为十六进制数字字符串,同时保持前导零? [复制]