【问题标题】: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 binary formatting bitwise-operators


【解决方案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, '#0{}b'.format(length + 2))
    

    【讨论】:

    • 可以使用相同的格式语言为您包含前缀。使用#。还有format(),这样就不用做一个完整的字符串模板了。
    【解决方案5】:

    使用 Python >= 3.6 时,最简洁的方法是使用 f-stringsstring 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:0{n}b}")
    00000101
    

    在这里,我使用以下格式打印变量 x:我希望它以 b(二进制)格式左填充 0 以具有长度 = n。有关更多信息,请参阅先前答案中的 Format Specification Mini-Language。

    【讨论】:

      【解决方案8】:

      你可以使用这样的东西

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

      【讨论】:

      • 请至少为您的代码 sn-p 使用代码块。如果你真的希望它是一个好的答案,那么还要添加一些关于为什么这个解决方案正在解决 OP 问题的 cmets。
      • 您不需要使用不同的字符串格式样式来添加可变宽度。只需添加另一个占位符:"{:0{l}b}".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 开头。
      猜你喜欢
      • 2015-03-09
      • 2015-07-20
      • 1970-01-01
      • 1970-01-01
      • 2015-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多