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

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.formatformat() 更灵活,因为它允许您一次执行多个变量。我一直忘记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 中将二进制字符串转换为带有前导零的十六进制字符串

将 int 转换为带前导零的十六进制

C编程十进制到二进制 - 将前导零添加到递归方法

在 Java 中,如何将字节数组转换为十六进制数字字符串,同时保持前导零? [复制]

在 Java 中,如何将字节数组转换为十六进制数字字符串,同时保持前导零? [复制]

C# 将字符串转换为双精度/十进制并返回字符串,保留尾随零,为千位添加逗号