Python int到二进制?

Nat*_*ate 475 python

是否有任何固定的Python方法可以将Integer(或Long)转换为Python中的二进制字符串?

Google上有无数的dec2bin()函数......但我希望我可以使用内置的函数/库.

Tun*_*yen 671

Python的字符串格式方法可以采用格式规范.

>>> "{0:b}".format(37)
'100101'
Run Code Online (Sandbox Code Playgroud)

格式化Python 2的规范文档

格式化Python 3的规范文档

  • `str.format()`只是格式化一个值是过度的.直接进入[`format()`函数](https://docs.python.org/2/library/functions.html#format):`format(n,'b')`.无需解析占位符并将其与参数匹配,直接进行值格式化操作本身.如果需要将格式化结果放在更长的字符串中(例如将其用作模板),则只使用`str.format()`. (72认同)
  • @mike:或者使用格式规范.将带有"0"的数字位数添加到格式化字符串中:`format(10,'016b')`格式化为带有前导零的16位数字. (21认同)
  • Python3.7 或更高版本中的 f"{37:b}"。 (8认同)
  • 通常会使用 4/8/... 位表示:`"{:08b}".format(37)` (5认同)
  • 谢谢董.什么是扭转这种操作的pythonic方法? (2认同)
  • 这里有一个关于负数的问题。@nate 没有明确指定在这种情况下所需的输出是什么,但纯粹以二进制数表示,不存在负号。所以最高有效位一般用来表示负号。假设我们使用 8 位整数,-37 将是“0b10100101”。但对于无符号整数,该值将是 165。所以事情并非如此简单。答案应该反映这一点。 (2认同)

Joh*_*uhy 418

如果你正在寻找bin()相同的hex(),它是在python 2.6中添加的.

例:

>>> bin(10)
'0b1010'
Run Code Online (Sandbox Code Playgroud)

  • 另请注意,执行`str(bin(i))[2:]`(对于1000000ops为0.369s)比"{0:b}"更快.format(i)`(对于1000000ops为0.721s) (61认同)
  • @mVChr如果有人将数字转换为ASCII二进制表示,我真的希望速度无关紧要. (58认同)
  • @mVChr:`str.format()`无论如何都是错误的工具,你可以使用`format(i,'b')`代替.考虑到这也为您提供了填充和对齐选项; `format(i,'016b')`格式化为16位零填充二进制数.要用`bin()做同样的事情,你必须添加一个`str.zfill()`调用:`bin(i)[2:].zfill(16)`(不需要调用`str() `!).`format()`的可读性和灵活性(动态格式化更难以使用`bin()`)是很好的权衡,除非必须,否则不要优化性能,直到那时为可维护性进行优化. (28认同)
  • 当然,在python 3.6及更高版本中,您现在可以使用`f“ {37:b}”`。 (3认同)

pax*_*blo 60

Python实际上确实已经内置了一些内容,能够执行诸如的操作'{0:b}'.format(42),这将为您提供位模式(在字符串中)42,或101010.


对于更一般的哲学,任何语言或图书馆都不会为其用户群提供他们想要的一切.如果您在一个无法提供所需内容的环境中工作,那么您应该在开发时收集代码片段,以确保您不必再编写两次相同的内容.例如:

def int_to_bin_string(i):
    if i == 0:
        return "0"
    s = ''
    while i:
        if i & 1 == 1:
            s = "1" + s
        else:
            s = "0" + s
        i //= 2
    return s
Run Code Online (Sandbox Code Playgroud)

假设Python还没有更简单的方法,它将根据十进制值构造二进制字符串.

一般的想法是使用代码(按优先顺序):

  • 语言或内置库.
  • 具有合适许可证的第三方库.
  • 你自己的收藏.
  • 您需要编写的新内容(并保存在您自己的集合中以供日后使用).


kct*_*529 36

作为参考:

def toBinary(n):
    return ''.join(str(1 & int(n) >> i) for i in range(64)[::-1])
Run Code Online (Sandbox Code Playgroud)

此函数可以转换一个大的正整数18446744073709551615,表示为字符串'1111111111111111111111111111111111111111111111111111111111111111'.

它可以被修改为提供更大的整数,但它可能不像"{0:b}".format()或更方便bin().

  • 有了Python的旧版本,这正是我所需要的,谢谢。 (2认同)

Mar*_*oma 36

如果你想要一个没有0b前缀的文本表示,你可以使用这个:

get_bin = lambda x: format(x, 'b')

print(get_bin(3))
>>> '11'

print(get_bin(-3))
>>> '-11'
Run Code Online (Sandbox Code Playgroud)

当你想要一个n位表示:

get_bin = lambda x, n: format(x, 'b').zfill(n)
>>> get_bin(12, 32)
'00000000000000000000000000001100'
>>> get_bin(-12, 32)
'-00000000000000000000000000001100'
Run Code Online (Sandbox Code Playgroud)

或者,如果您希望有一个功能:

def get_bin(x, n=0):
    """
    Get the binary representation of x.

    Parameters
    ----------
    x : int
    n : int
        Minimum number of digits. If x needs less digits in binary, the rest
        is filled with zeros.

    Returns
    -------
    str
    """
    return format(x, 'b').zfill(n)
Run Code Online (Sandbox Code Playgroud)

  • 或者只使用`format(整数,'b')`.`bin()`是一个调试工具,专门用于生成*Python二进制整数文字语法*,`format()`用于生成特定格式. (5认同)
  • 更多替代方案:如果要使宽度动态化,而不是`str.zfill()`,可以使用带有动态第二个参数的`str.format()`或`format()`:`'{0:0 {1} b}'.format(x,n)`或`format(b,'0 {} b'.format(n))`. (4认同)
  • 从文档中:*结果是有效的Python表达式*。目的是产生一个Python表达式,而不是产生最终用户表示。oct()和hex()也一样。 (2认同)

Azi*_*lto 14

带有lambda的单线程:

>>> binary = lambda n: '' if n==0 else binary(n/2) + str(n%2)
Run Code Online (Sandbox Code Playgroud)

测试:

>>> binary(5)
'101'
Run Code Online (Sandbox Code Playgroud)



编辑:

但是之后 :(

t1 = time()
for i in range(1000000):
     binary(i)
t2 = time()
print(t2 - t1)
# 6.57236599922
Run Code Online (Sandbox Code Playgroud)

比较

t1 = time()
for i in range(1000000):
    '{0:b}'.format(i)
t2 = time()
print(t2 - t1)
# 0.68017411232
Run Code Online (Sandbox Code Playgroud)


Xia*_*ang 14

一种简单的方法是使用字符串格式,请参阅此页面.

>> "{0:b}".format(10)
'1010'
Run Code Online (Sandbox Code Playgroud)

如果你想拥有一个固定长度的二进制字符串,你可以使用这个:

>> "{0:{fill}8b}".format(10, fill='0')
'00001010'
Run Code Online (Sandbox Code Playgroud)

如果需要两个补码,则可以使用以下行:

'{0:{fill}{width}b}'.format((x + 2**n) % 2**n, fill='0', width=n)
Run Code Online (Sandbox Code Playgroud)

其中n是二进制字符串的宽度.


Rom*_*lka 14

我很惊讶没有提到使用 Python 3.6 及更高版本支持的格式化字符串来完成此操作的好方法。域名注册地址:

>>> number = 1
>>> f'0b{number:08b}'
'0b00000001'
Run Code Online (Sandbox Code Playgroud)

更长的故事

这是 Python 3.6 提供的格式化字符串的功能:

>>> x, y, z = 1, 2, 3
>>> f'{x} {y} {2*z}'
'1 2 6'
Run Code Online (Sandbox Code Playgroud)

您也可以请求二进制文件:

>>> f'{z:b}'
'11'
Run Code Online (Sandbox Code Playgroud)

指定宽度:

>>> f'{z:8b}'
'      11'
Run Code Online (Sandbox Code Playgroud)

请求零填充:

f'{z:08b}'
'00000011'
Run Code Online (Sandbox Code Playgroud)

并添加公共前缀来表示二进制数:

>>> f'0b{z:08b}'
'0b00000011'
Run Code Online (Sandbox Code Playgroud)

您也可以让 Python 为您添加前缀,但我不像上面的版本那么喜欢它,因为您必须考虑前缀的宽度:

>>> f'{z:#010b}'
'0b00000011'
Run Code Online (Sandbox Code Playgroud)

更多信息可在Formatted string literalsFormat Specification Mini-Language 的官方文档中找到。


Bob*_*ein 11

替代方案摘要:

n=42
assert  "-101010" == format(-n, 'b')
assert  "-101010" == "{0:b}".format(-n)
assert  "-101010" == (lambda x: x >= 0 and str(bin(x))[2:] or "-" + str(bin(x))[3:])(-n)
assert "0b101010" == bin(n)
assert   "101010" == bin(n)[2:]   # But this won't work for negative numbers.
Run Code Online (Sandbox Code Playgroud)

贡献者包括John Fouhy,Tung Nguyen,mVChr,Martin Thoma.和Martijn Pieters.

  • `str.format()`只是格式化一个值是过度的.直接进入`format()`函数:`format(n,'b')`.无需解析占位符并将其与参数匹配. (5认同)

gre*_*pit 9

这是针对python 3的,它保持前导零!

print(format(0, '08b'))
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

  • 我很欣赏这个简单的答案。 (3认同)
  • 太感谢了。很遗憾这个答案如此之低。 (3认同)

San*_*rsu 9

>>> format(123, 'b')
'1111011'
Run Code Online (Sandbox Code Playgroud)


Dea*_*anM 7

对于我们这些需要将有符号整数(范围 -2**(digits-1) 到 2**(digits-1)-1)转换为 2 的补码二进制字符串的人来说,这是有效的:

def int2bin(integer, digits):
    if integer >= 0:
        return bin(integer)[2:].zfill(digits)
    else:
        return bin(2**digits + integer)[2:]
Run Code Online (Sandbox Code Playgroud)

这产生:

>>> int2bin(10, 8)
'00001010'
>>> int2bin(-10, 8)
'11110110'
>>> int2bin(-128, 8)
'10000000'
>>> int2bin(127, 8)
'01111111'
Run Code Online (Sandbox Code Playgroud)


Dol*_*nga 6

接受的答案没有解决负数,我将对此进行介绍。除了上面的答案之外,您还可以只使用binhex函数。反之亦然,使用二进制表示法:

>>> bin(37)
'0b100101'
>>> 0b100101
37
Run Code Online (Sandbox Code Playgroud)

但对于负数,事情会变得更加复杂。该问题没有指定您希望如何处理负数。

Python 只是添加一个负号,因此 -37 的结果将是这样的:

>>> bin(-37)
'-0b100101'
Run Code Online (Sandbox Code Playgroud)

在计算机/硬件二进制数据中,不存在负号。我们只有 1 和 0。因此,如果您正在读取或生成要由其他软件/硬件处理的二进制数据流,您需要首先了解所使用的符号。

一种表示法是符号-数值表示法,其中第一位表示负号,其余为实际值。在这种情况下,-37 将是0b1100101,37 将是0b0100101。这看起来像 python 生成的结果,但只需在前面添加 0 或 1 表示正/负数。

比较常见的是补码表示法,看起来比较复杂,而且结果与python的字符串格式化有很大不同。您可以阅读链接中的详细信息,但对于 8 位有符号整数, -37 为0b11011011, 37 为0b00100101

Python 没有简单的方法来生成这些二进制表示。您可以使用numpy将二进制补码值转换为 python 整数:

>>> import numpy as np
>>> np.int8(0b11011011)
-37
>>> np.uint8(0b11011011)
219
>>> np.uint8(0b00100101)
37
>>> np.int8(0b00100101)
37
Run Code Online (Sandbox Code Playgroud)

但我不知道用内置函数做相反的事情的简单方法。bitstring可以提供帮助。

>>> from bitstring import BitArray
>>> arr = BitArray(int=-37, length=8)
>>> arr.uint
219
>>> arr.int
-37
>>> arr.bin
'11011011'
>>> BitArray(bin='11011011').int
-37
>>> BitArray(bin='11011011').uint
219
Run Code Online (Sandbox Code Playgroud)


小智 6

Python 3.6 添加了一种新的字符串格式化方法,称为格式化字符串文字或 \xe2\x80\x9cf-strings\xe2\x80\x9d。\n示例:

\n
name = \'Bob\'\nnumber = 42\nf"Hello, {name}, your number is {number:>08b}"\n
Run Code Online (Sandbox Code Playgroud)\n

输出将是“Hello, Bob, your number is 00001010!”

\n

关于这个问题的讨论可以在这里找到 -这里

\n


Rez*_*tin 5

通过使用按位运算符的另一种算法的另一种解决方案.

def int2bin(val):
    res=''
    while val>0:
        res += str(val&1)
        val=val>>1     # val=val/2 
    return res[::-1]   # reverse the string
Run Code Online (Sandbox Code Playgroud)

没有反转字符串的更快版本.

def int2bin(val):
   res=''
   while val>0:
       res = chr((val&1) + 0x30) + res
       val=val>>1    
   return res 
Run Code Online (Sandbox Code Playgroud)


pit*_*all 5

使用numpy pack / unpackbits,它们是您最好的朋友。

Examples
--------
>>> a = np.array([[2], [7], [23]], dtype=np.uint8)
>>> a
array([[ 2],
       [ 7],
       [23]], dtype=uint8)
>>> b = np.unpackbits(a, axis=1)
>>> b
array([[0, 0, 0, 0, 0, 0, 1, 0],
       [0, 0, 0, 0, 0, 1, 1, 1],
       [0, 0, 0, 1, 0, 1, 1, 1]], dtype=uint8)
Run Code Online (Sandbox Code Playgroud)


Ski*_* Dz 5

你可以这样做:

bin(10)[2:]
Run Code Online (Sandbox Code Playgroud)

或者 :

f = str(bin(10))
c = []
c.append("".join(map(int, f[2:])))
print c
Run Code Online (Sandbox Code Playgroud)


Tom*_*ale 5

numpy.binary_repr(num, width=None)

\n\n

上面文档链接中的示例:

\n\n
\n
>>> np.binary_repr(3)\n\'11\'\n>>> np.binary_repr(-3)\n\'-11\'\n>>> np.binary_repr(3, width=4)\n\'0011\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

当输入数为负且指定宽度时,返回两个\xe2\x80\x99s补码:

\n\n
>>> np.binary_repr(-3, width=3)\n\'101\'\n>>> np.binary_repr(-3, width=5)\n\'11101\'\n
Run Code Online (Sandbox Code Playgroud)\n
\n


Joh*_*bes 5

由于前面的答案大多使用format(),因此这是f字符串实现。

integer = 7
bit_count = 5
print(f'{integer:0{bit_count}b}')
Run Code Online (Sandbox Code Playgroud)

输出:

00111

为方便起见,这里是格式化字符串文字的python docs链接:https : //docs.python.org/3/reference/lexical_analysis.html#f-strings