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

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

评论

相反,有关纯字符串处理算法,请参见此。

#1 楼

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

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


Python 2的格式规范文档

Python 3的格式规范文档

评论


只格式化一个值的str.format()是过大的。直接转到format()函数:format(n,'b')。无需解析占位符并将其与参数匹配,就直接进行值格式化操作本身。仅在需要将格式化结果放在更长的字符串中(例如,将其用作模板)时,才使用str.format()。

–马丁·彼得斯(Martijn Pieters)♦
2015年12月10日10:23



@mike:或使用格式规范。将以0开头的数字添加到格式字符串:format(10,'016b')format以以0开头的16位数字。

–马丁·彼得斯(Martijn Pieters)♦
2015年12月10日10:24



在这种情况下,可以将“ {0:b}”中的0删除吗?我的意思是,在仅格式化一个数字的情况下,放置“ {:b}”是正确的,不是吗?

–tomasyany
16年7月28日在23:53

通常使用4/8 / ...位表示形式:“ {:08b}”。format(37)

–火花
18年8月14日在21:51

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

– D. A.
19年7月18日在4:30

#2 楼

如果要查找与bin()等效的hex(),它是在python 2.6中添加的。

示例:

>>> bin(10)
'0b1010'


评论


另请注意,执行str(bin(i))[2:](对于1000000ops为0.369s)比“ {0:b}”。format(i)(对于1000000ops为0.721s)更快

– mVChr
13年10月30日在7:55

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

–尼克T
2014年2月5日下午5:04

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

–马丁·彼得斯(Martijn Pieters)♦
2015年12月10日10:28



[2:]是什么意思?

– zero_cool
17年8月18日在20:43

当然,在python 3.6及更高版本中,您现在可以使用f“ {37:b}”。

–卢克·戴维斯(Luke Davis)
17年11月6日在6:48

#3 楼

Python实际上确实已经为此内置了一些功能,能够执行'{0:b}'.format(42)之类的操作,这将为您提供42101010的位模式(以字符串形式)。


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

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


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

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


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

评论


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

–安德烈亚斯·马格努森(Andreas Magnusson)
1月9日在11:31

@Andreas,我建议使用'{0:b}'。format(42),slow方法只是如何通用地执行此操作的示例,取决于是否为O(n ^ 2),具体取决于实际使用的语言。它看起来像Python,因为Python是理想的伪代码语言,因此我将对其进行更改以使其更加清晰。

– paxdiablo
1月9日13:25

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

–安德烈亚斯·马格努森(Andreas Magnusson)
1月9日13:28



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

– paxdiablo
1月9日15:11



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

–安德烈亚斯·马格努森(Andreas Magnusson)
1月9日18:30

#4 楼

如果您想要不带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)


评论


或者只使用format(integer,'b')。 bin()是一种调试工具,专门用于生成Python二进制整数文字语法,format()用于生成特定格式。

–马丁·彼得斯(Martijn Pieters)♦
2015年12月10日10:21



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

–马丁·托马
2015年12月10日上午10:36

从文档中:结果是有效的Python表达式。目的是产生一个Python表达式,而不是产生最终用户表示。 oct()和hex()也一样。

–马丁·彼得斯(Martijn Pieters)♦
2015年12月10日上午10:37

更多替代方法:如果要使宽度动态化,可以使用带有动态第二个参数'{0:0 {1} b}'的str.format()或format()代替str.zfill()。 format(x,n)或format(b,'0 {} b'.format(n))。

–马丁·彼得斯(Martijn Pieters)♦
2015年12月10日上午10:41

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

–马丁·托马
2015年12月10日上午10:45

#5 楼

作为参考:

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


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

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

评论


@GarethDavidson这是哪个版本?进行谷歌搜索时,明确指出该信息可能会在将来有更大的用途。

–狼
19年4月11日在10:56



我认为是2.7版。我怀疑它是否可以在3.x中运行

–加雷斯·戴维森(Gareth Davidson)
19年4月11日在22:24

#6 楼

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

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


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

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


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

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


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

#7 楼

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

print(format(0, '08b'))




评论


我很欣赏简单的答案。

–reergymerej
3月20日下午2:30

#8 楼

带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
17年1月15日在19:15

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

–阿齐兹·阿尔托(Aziz Alto)
17年1月16日在6:10

#9 楼

正如前面的回答,大多数使用format()的方法一样,这是一个f字符串实现。

integer = 7
bit_count = 5
print(f'{integer:0{bit_count}b}')


输出:


00111


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

#10 楼

替代方案摘要:

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 Fouhy,Tung Nguyen,mVChr和Martin Thoma。和Martijn Pieters。

评论


只格式化一个值的str.format()是过大的。直接转到format()函数:format(n,'b')。无需解析占位符并将其与参数匹配。

–马丁·彼得斯(Martijn Pieters)♦
2015年12月10日10:23



#11 楼

>>> format(123, 'b')
'1111011'


#12 楼

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


#13 楼

我很惊讶,没有提到使用格式化字符串完成此操作的好方法。 TLDR:
>>> number = 1
>>> f'0b{number:08b}'
'0b00000001'

长篇故事
这是格式化字符串的功能:
>>> x, y, z = 1, 2, 3
>>> f'{x} {y} {2*z}'
'1 2 6'

您也可以请求二进制文件:
>>> f'{z:b}'
'11'

指定宽度:
>>> f'{z:8b}'
'      11'

请求零填充:
f'{z:08b}'
'00000011'

并添加二进制的通用后缀:
>>> f'0b{z:08b}'
'0b00000011'


评论


要添加下划线:f'0b {z:09_b}'=>'0b0000_0011'

–弗雷德里克
10月23日10:34

字节序如何?一个可以改变吗?

–lesolorzanov
10月26日11:24

这超出了这个问题的范围。最重要的第一点是无论系统字节顺序如何都如何在位置系统中写入数字的规范方法,这只是一个实现细节。您可以执行f'{z:08b}'[::-1]来实现最低有效字节的优先顺序,但是在大多数情况下,恕我直言这会引起混乱...

–罗马·帕维尔卡(Roman Pavelka)
10月26日18:08



#14 楼

使用numpy打包/拆包,它们是您最好的朋友。

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)


评论


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

–汤姆·黑尔
19年4月30日在9:30

doco说:将uint8数组的元素解压缩为二进制值输出数组。非常适合高达255的值。

–汤姆·黑尔
19年4月30日在9:32

#15 楼

您可以这样做:

bin(10)[2:]


或:

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


评论


bin(n).replace(“ 0b”,“”)

–小一点
3月5日6:34

#16 楼

除非我误解了二进制字符串的含义,否则我认为您要查找的模块是struct

评论


新位置。

–艾伦
5月14日15:33

#17 楼

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

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)
19年4月15日在12:21

#18 楼

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

print binary(10)


输出:


1010


#19 楼

Python 3.6添加了一种新的字符串格式化方法,称为格式化字符串文字或“ f-strings”。
示例:
name = 'Bob'
number = 42
f"Hello, {name}, your number is {number:>08b}"

输出将是“ Hello,Bob,您的数字是00001010!”
可以在这里找到有关此问题的讨论-在这里

#20 楼

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

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


#21 楼

n=input()
print(bin(n).replace("0b", ""))


#22 楼

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'



#23 楼

有点类似的解决方案

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 


#24 楼

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

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


评论


需要调试。调用dectobin(10)结果为'0101'

–内特
14-10-27在19:31

#25 楼

这是使用常规数学的另一种方式,没有循环,只有递归。 (特殊情况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']


评论


0返回''很奇怪,应该是'0'...

–安德烈亚斯·马格努森(Andreas Magnusson)
9月11日14:00



#26 楼

计算器,具有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')


#27 楼


计算数字的二进制数:


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


#28 楼

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")


评论


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

– Artless
17年4月27日在9:00

#29 楼

我发现了一种使用矩阵运算将十进制转换为二进制的方法。
E是输出二进制数据,格式为1 x M二进制矩阵。

#30 楼

我觉得Martijn Pieter的评论值得一提:

binary_string = format(value, '0{}b'.format(width))


对我来说既清晰又多才多艺。