Python int转换为二进制字符串?


529

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

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


相反,对于纯字符串处理算法,请参见this
CopyPasteIt

Answers:


749

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

>>> "{0:b}".format(37)
'100101'

适用于Python 2的格式规范文档

适用于Python 3的格式规范文档


86
str.format()仅格式化一个值就太过分了。直接进入format()函数format(n, 'b')。无需解析占位符并将其与参数匹配,就直接进行值格式化操作本身。仅str.format()在需要将格式化结果放在更长的字符串中时使用(例如,将其用作模板)。
马丁·彼得斯

29
@mike:或使用格式规范。将带前缀的数字位数添加0到格式字符串:format(10, '016b')格式化为带前导零的16位数字。
马丁·皮特斯

在这种情况下0"{0:b}"可以删除in 吗?我的意思是,在仅格式化一个数字的情况下,正确输入"{:b}"是不是?
tomasyany

1
通常一个人会使用4/8 / ...位表示形式:"{:08b}".format(37)
Sparkler

2
在Python3.7或更高版本中为f“ {37:b}”。
DA

471

如果您正在寻找bin()等同于hex(),它是在python 2.6中添加的。

例:

>>> bin(10)
'0b1010'

66
另请注意,执行str(bin(i))[2:](1000000ops为0.369s)比"{0:b}".format(i)(1000000ops为0.721s)
更快

64
@mVChr如果有人将数字转换为ASCII二进制表示形式,我真的希望速度无关紧要。
尼克T

29
@mVChr:str.format()还是错误的工具,您应该使用它format(i, 'b')。考虑到这也给您填充和对齐选项;format(i, '016b')格式化为16位零填充二进制数。为此,bin()您必须添加一个str.zfill()呼叫:(bin(i)[2:].zfill(16)无需呼叫str()!)。format()的可读性和灵活性(使用很难进行动态格式化bin())是一个很大的权衡,除非必须这样做,否则请不要为性能而优化,然后再针对可维护性进行优化。
马丁·彼得斯

[2:]是什么意思?
zero_cool

4
当然,有了python 3.6+,您现在可以使用了f"{37:b}"
卢克·戴维斯

63

Python的实际确实已经内建了对这个东西,做如操作的能力'{0:b}'.format(42),这将给你的位模式(在一个字符串)42,或101010


对于更一般的哲学,没有语言或库会向用户群提供他们想要的一切。如果您所处的环境不能完全满足您的需求,则在开发过程中应收集代码片段,以确保您不必重复编写同一件事。例如伪代码:

define intToBinString, receiving intVal:
    if intVal is equal to zero:
        return "0"
    set strVal to ""
    while intVal is greater than zero:
        if intVal is odd:
            prefix "1" to strVal
        else:
            prefix "0" to strVal
        divide intVal by two, rounding down
    return strVal

它将根据十进制值构造您的二进制字符串。请记住,这是伪代码的通用位,虽然这可能不是有效的方式,但是您似乎建议进行迭代,但这并没有太大的区别。它实际上只是作为如何完成操作的指南。

总体思路是使用代码(按优先顺序排列):

  • 语言或内置库。
  • 具有适当许可证的第三方库。
  • 你自己的收藏。
  • 您需要编写一些新内容(并保存在自己的收藏夹中以备后用)。

1
在这个答案中有一些好的建议。太糟糕的是,代码会不必要地变慢。您提出一个O(N)可以做的O(N ^ 2)算法。问题部分在s = "1" + ss = "0" + s行中。每个都不必要地复制s。您应该在返回字符串之前反转字符串。
Andreas Magnusson

@Andreas,我提议使用的'{0:b}'.format(42)是慢速方法,只是该方法的一般示例,根据实际使用的语言,它可能为O(n ^ 2),也可能不是O(n ^ 2)。它看起来像Python,因为Python是理想的伪代码语言,因此我将对其进行更改以使其更加清晰。
paxdiablo

实际上,这是一种非常深奥的语言,s = "1" + ss它是字符串类型时不是O(N)。也许是一种所有字符串都向后存储或每个字符都是链表中的节点的语言?对于任何典型的语言,字符串基本上都是字符数组。在这种情况下,给字符串加上前缀需要进行复制,否则您将如何将该字符放在其他字符之前?
Andreas Magnusson

我可以轻松地设想一个字符串类型,它由一个内存块组成,在该内存块中该字符串在该块内右对齐,并偏移其起始字符。要给字符加上前缀,您只需减少偏移量并将字符存储在那里。是的,这是深奥的,但它没有什么意义,我争论带着几分伪代码可能现实问题,特别是因为你可能不会有超过几十位/迭代。如果您的数据量很小,即使是冒犯性很强的冒泡排序也足够了:-)无论如何,我都会添加关于效率的注释。
paxdiablo

当然,如果效率很重要,那么您可能就不会选择python。依我的经验,还是经常发生这样的情况,即使用O(N²)算法天真地编写并使用较小数据集进行测试的代码很快就可以用于更大的数据集,因为“它似乎可以工作”。突然之间,您的代码需要花费数小时才能运行,而修复后的代码可能仅需几秒钟。O(N²)算法很隐蔽,因为它们似乎工作了一段时间,但是当您的数据扩展时,它们却无法工作,到那时,编写它们的人就退出了,而且没人知道事情为什么会永远持续下去。
安德烈亚斯·马格努森

41

如果要使用不带0b前缀的文本表示形式,则可以使用以下代码:

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

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

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

当您需要n位表示形式时:

get_bin = lambda x, n: format(x, 'b').zfill(n)
>>> get_bin(12, 32)
'00000000000000000000000000001100'
>>> get_bin(-12, 32)
'-00000000000000000000000000001100'

或者,如果您更喜欢具有以下功能:

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)

5
或只是使用format(integer, 'b')bin()是一个调试工具,专门用于产生Python二进制整数文字语法format()旨在产生特定格式。
马丁·彼得斯

1
@MartijnPieters非常感谢您提及它。我已经调整了解决方案。您怎么知道这bin()是一个旨在产生Python二进制整数文字语法的调试工具?我在文档中找不到。
Martin Thoma 2015年

2
从文档中:结果是一个有效的Python表达式。目的是产生一个Python表达式,而不是产生最终用户表示。oct()和和相同hex()
马丁·彼得斯

4
更多替代方法:如果要使宽度动态化,则str.zfill()可以使用str.format()或将其format()与动态第二个参数结合使用:'{0:0{1}b}'.format(x, n)format(b, '0{}b'.format(n))
马丁·彼得斯

@MartijnPieters哇,非常感谢您的投入!我不知道格式是否可行。但是,我认为我当前的答案zfill比动态第二个参数更易于阅读和理解,因此我将继续保留。
Martin Thoma 2015年

37

作为参考:

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

此函数可以转换一个大的正整数18446744073709551615,以string表示'1111111111111111111111111111111111111111111111111111111111111111'

可以修改它以使用更大的整数,尽管它可能不如"{0:b}".format()或方便bin()


@GarethDavidson这是哪个版本?谷歌搜索时,明确声明此内容可能会在将来有更大的用途。

我认为是2.7版。我怀疑它会在3.x的工作
加雷斯·戴维森

17

一种简单的方法是使用字符串格式,请参见本页

>> "{0:b}".format(10)
'1010'

如果要固定长度的二进制字符串,则可以使用以下命令:

>> "{0:{fill}8b}".format(10, fill='0')
'00001010'

如果需要二进制补码,则可以使用以下行:

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

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



14

lambda的单线

>>> binary = lambda n: '' if n==0 else binary(n/2) + str(n%2)

测试:

>>> binary(5)
'101'



编辑

但是之后 :(

t1 = time()
for i in range(1000000):
     binary(i)
t2 = time()
print(t2 - t1)
# 6.57236599922

相较于

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

虽然返回0的“”。0的法线表示不是'0'吗?
Dietbacon

如果您想看到0 :),则可以替换'''0',但是它将为任何数字添加前导0。
阿齐兹·阿尔托

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.

贡献者包括John FouhyTung NguyenmVChrMartin Thoma。和马丁·彼得斯(Martijn Pieters)。


6
str.format()仅格式化一个值就太过分了。直接转到format()函数:format(n, 'b')。无需解析占位符并将其与参数匹配。
马丁·彼得斯



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)

问题是关于字符串表示形式。仍然,这恰好是我一直在寻找的内容,而无需先通过字符串!:)
汤姆·黑尔

DOCO说:一个的解压缩元件uint8阵列为二进制值输出阵列。所以,好值高达255
汤姆·黑尔

5

对于我们这些需要将带符号整数(范围-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:]

这将产生:

>>> int2bin(10, 8)
'00001010'
>>> int2bin(-10, 8)
'11110110'
>>> int2bin(-128, 8)
'10000000'
>>> int2bin(127, 8)
'01111111'


4

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

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

更快的版本而无需反转字符串。

def int2bin(val):
   res=''
   while val>0:
       res = chr((val&1) + 0x30) + res
       val=val>>1    
   return res 

第二个版本肯定不会更快,因为您最终得到的是O(N ^ 2)算法而不是O(N)。我已经看到这样的事情会杀死一个应用程序(在性能方面),因为开发人员认为在最后进行额外的传递比在第一个循环中执行一些额外的操作要慢。修复后,运行时间将从几天缩短到几秒钟。
Andreas Magnusson

4
def binary(decimal) :
    otherBase = ""
    while decimal != 0 :
        otherBase  =  str(decimal % 2) + otherBase
        decimal    //=  2
    return otherBase

print binary(10)

输出:

1010


4

你可以这样:

bin(10)[2:]

要么 :

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

滨(N).replace( “0B”, “”)
塞纳小

3

这是我刚刚实现的代码。这不是一种方法,但是您可以将其用作现成的功能

def inttobinary(number):
  if number == 0:
    return str(0)
  result =""
  while (number != 0):
      remainder = number%2
      number = number/2
      result += str(remainder)
  return result[::-1] # to invert the string

3

这是使用divmod()功能的简单解决方案,该功能返回提醒和不带分数的除法结果。

def dectobin(number):
    bin = ''
    while (number >= 1):
        number, rem = divmod(number, 2)
        bin = bin + str(rem)
    return bin

需要调试。调用dectobin(10)导致“0101”
奈特


3

numpy.binary_repr(num, width=None)

上面的文档链接中的示例:

>>> np.binary_repr(3)
'11'
>>> np.binary_repr(-3)
'-11'
>>> np.binary_repr(3, width=4)
'0011'

当输入数字为负并且指定了宽度时,将返回二进制补码:

>>> np.binary_repr(-3, width=3)
'101'
>>> np.binary_repr(-3, width=5)
'11101'

2

有点类似的解决方案

def to_bin(dec):
    flag = True
    bin_str = ''
    while flag:
        remainder = dec % 2
        quotient = dec / 2
        if quotient == 0:
            flag = False
        bin_str += str(remainder)
        dec = quotient
    bin_str = bin_str[::-1] # reverse the string
    return bin_str 

2

这是使用常规数学的另一种方式,没有循环,只有递归。(特殊情况0不返回任何内容)。

def toBin(num):
  if num == 0:
    return ""
  return toBin(num//2) + str(num%2)

print ([(toBin(i)) for i in range(10)])

['', '1', '10', '11', '100', '101', '110', '111', '1000', '1001']

2

计算器,具有DEC,BIN,HEX的所有必要功能:(使用Python 3.5进行制造和测试)

您可以更改输入的测试编号并获得转换后的编号。

# CONVERTER: DEC / BIN / HEX

def dec2bin(d):
    # dec -> bin
    b = bin(d)
    return b

def dec2hex(d):
    # dec -> hex
    h = hex(d)
    return h

def bin2dec(b):
    # bin -> dec
    bin_numb="{0:b}".format(b)
    d = eval(bin_numb)
    return d,bin_numb

def bin2hex(b):
    # bin -> hex
    h = hex(b)
    return h

def hex2dec(h):
    # hex -> dec
    d = int(h)
    return d

def hex2bin(h):
    # hex -> bin
    b = bin(h)
    return b


## TESTING NUMBERS
numb_dec = 99
numb_bin = 0b0111 
numb_hex = 0xFF


## CALCULATIONS
res_dec2bin = dec2bin(numb_dec)
res_dec2hex = dec2hex(numb_dec)

res_bin2dec,bin_numb = bin2dec(numb_bin)
res_bin2hex = bin2hex(numb_bin)

res_hex2dec = hex2dec(numb_hex)
res_hex2bin = hex2bin(numb_hex)



## PRINTING
print('------- DECIMAL to BIN / HEX -------\n')
print('decimal:',numb_dec,'\nbin:    ',res_dec2bin,'\nhex:    ',res_dec2hex,'\n')

print('------- BINARY to DEC / HEX -------\n')
print('binary: ',bin_numb,'\ndec:    ',numb_bin,'\nhex:    ',res_bin2hex,'\n')

print('----- HEXADECIMAL to BIN / HEX -----\n')
print('hexadec:',hex(numb_hex),'\nbin:    ',res_hex2bin,'\ndec:    ',res_hex2dec,'\n')

2

要计算数字的二进制数:

print("Binary is {0:>08b}".format(16))

要计算数字的十六进制十进制

print("Hexa Decimal is {0:>0x}".format(15))

要计算所有二进制数,直到16 ::

for i in range(17):
   print("{0:>2}: binary is {0:>08b}".format(i))

计算十六进制小数,直到17

 for i in range(17):
    print("{0:>2}: Hexa Decimal is {0:>0x}".format(i))
##as 2 digit is enogh for hexa decimal representation of a number

1

如果你愿意放弃“纯” Python的,但收获了很多火力,有贤者 - 这里的例子

sage: a = 15
sage: a.binary()
'1111'

您会注意到它以字符串形式返回,因此要将其用作数字,您需要执行以下操作

sage: eval('0b'+b)
15

1
try:
    while True:
        p = ""
        a = input()
        while a != 0:
            l = a % 2
            b = a - l
            a = b / 2
            p = str(l) + p
        print(p)
except:
    print ("write 1 number")

6
可能想对您在这里所做的事情添加一些解释。
Artless

1

我发现了一种使用矩阵运算将十进制转换为二进制的方法。

import numpy as np
E_mat = np.tile(E,[1,M])
M_order = pow(2,(M-1-np.array(range(M)))).T
bindata = np.remainder(np.floor(E_mat /M_order).astype(np.int),2)

E是输入十进制数据,M是二进制顺序。bindata是输出二进制数据,格式为1 x M二进制矩阵。


0

这是一个不断循环的简单的二进制到十进制转换器

t = 1
while t > 0:
    binaryNumber = input("Enter a binary No.")
    convertedNumber = int(binaryNumber, 2)

    print(convertedNumber)

print("")

这是OP想要的相反顺序。他们正在寻找int到二进制。您将二进制文件提供给int。
塞西莉亚

0

这是我的回答,效果很好..!

def binary(value) :
    binary_value = ''
    while value !=1  :
        binary_value += str(value%2)
        value = value//2
    return '1'+binary_value[::-1]

如果您传递值0怎么办?例如,binary(0)您会得到您所期望的吗?
Andreas Magnusson
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.