Pythonのintからバイナリ文字列?


530

PythonでInteger(またはLong)をバイナリ文字列に変換するための既定のPythonメソッドはありますか?

Googleには無数のdec2bin()関数があります...しかし、組み込みの関数/ライブラリを使用できることを期待していました。


反対テイクのために、純粋な文字列処理アルゴリズムのために、参照これを
CopyPasteIt

回答:


750

Pythonの文字列フォーマットメソッドは、フォーマット仕様を取ることができます。

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

Python 2の仕様ドキュメントのフォーマット

Python 3のフォーマットドキュメント


86
str.format()1つの値をフォーマットするだけではやり過ぎです。直行format()機能format(n, 'b')。プレースホルダーを解析して引数と照合する必要はありません。値のフォーマット操作自体に直接進みます。str.format()フォーマットされた結果をより長い文字列に配置する必要がある場合にのみ使用します(例:テンプレートとして使用)。
Martijn Pieters

29
@mike:または、フォーマット仕様を使用します。先行のある桁数を0フォーマット文字列に追加しformat(10, '016b')ます。先行ゼロのある16桁にフォーマットします。
Martijn Pieters

この場合、0イン"{0:b}"はドロップできませんか?つまり、フォーマットされている数値が1つだけの場合は、を置くのが正しいの"{:b}"ではないでしょうか。
tomasyany

1
通常、1は4/8 / ...ビット表現を使用します"{:08b}".format(37)
花火

2
f "{37:b}"(Python3.7以降)。
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)
mVChr

64
@mVChr誰かが数値をASCIIバイナリ表現に変換している場合、速度が問題にならないことを願っています。
Nick T

29
@mVChr:str.format()とにかく間違ったツールですformat(i, 'b')。代わりに使用します。ただし、パディングと配置のオプションも提供されることを考慮してください。format(i, '016b')16ビットのゼロが埋め込まれた2進数にフォーマットします。同じbin()ことを行うには、str.zfill()呼び出しを追加するbin(i)[2:].zfill(16)必要があります(呼び出す必要はありませんstr()!)。format()の可読性と柔軟性(を使用すると動的な書式設定ははるかに難しくなりますbin())は大きなトレードオフです。必要でない限り、パフォーマンスを最適化しないでください。その後、保守性を最適化します。
Martijn Pieters

[2:]はどういう意味ですか?
zero_cool 2017

4
もちろん、Python 3.6以降ではを使用できますf"{37:b}"
ルークデイビス

63

Pythonは実際に行い、すでにこのために建てられた何かを持っている、などの操作を行うための能力'{0:b}'.format(42)あなたのために(文字列の)ビット・パターンを与えるであろう、42またはを101010


より一般的な哲学としては、言語やライブラリがユーザーの望むすべてをユーザーに提供することはありません。必要なものが正確に提供されない環境で作業している場合は、開発時にコードのスニペットを収集して、同じものを2回書く必要がないようにする必要があります。たとえば、次のような疑似コード:

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

これは、10進数値に基づいてバイナリ文字列を構築します。ただし、これは疑似コードの一般的なビットであり、最も効率的な方法ではない可能性があることを覚えておいてください。それは実際にそれがどのように行われることができるかのガイドラインとして意図されただけです。

一般的な考え方は、(優先順に)からコードを使用することです。

  • 言語または組み込みライブラリ。
  • 適切なライセンスを持つサードパーティライブラリ。
  • あなた自身のコレクション。
  • あなたが書く必要がある新しい何か(そして後で使うためにあなた自身のコレクションに保存してください)。

1
この回答でいくつかの良いアドバイス。コードが不必要に遅いというのはあまりにも悪いことです。O(N)が行う場所にO(N ^ 2)アルゴを提案します。問題のある部分はs = "1" + sおよびs = "0" + s行にあります。それぞれがの不要なコピーを作成します。代わりに返す前に、文字列を逆にする必要があります。
Andreas Magnusson

@Andreas、私が使用することを提案したもの'{0:b}'.format(42)で、遅い方法は一般的にそれを行う方法の単なる例であり、実際に使用される言語に応じてO(n ^ 2)である場合とそうでない場合があります。Pythonは理想的な疑似コード言語であるため、Pythonのように見えるだけなので、それを明確にするために変更します。
paxdiablo

実際s = "1" + ssは、文字列型の場合、O(N)ではなかったかなり難解な言語になります。多分すべての文字列が逆方向に格納されている言語ですか、各文字がリンクされたリストのノードです?一般的な言語の場合、文字列は基本的に文字の配列です。その場合、文字列の前にコピーを作成する必要がありますが、他にどのようにして文字を他の文字の前に置きますか?
Andreas Magnusson

文字列がそのブロック内で右揃えされているメモリブロックと、その開始文字へのオフセットで構成される文字列型を簡単に想定できます。文字にプレフィックスを付けるには、オフセットを減らしてそこに文字を格納するだけです。はい、それ難解ですが、特に数十ビット/反復を超える可能性が低いため、疑似コードを少し使って現実の問題の可能性について議論することはほとんど意味がありません。データサイズが小さい場合は、非常に悪質なバブルソートでも十分です:-)いずれにしても、効率に関するメモを追加します。
paxdiablo

確かに、効率が重要であれば、おそらく最初からpythonを選択しないでしょう。それでも私の経験では、O(N²)アルゴを使用してナイーブに記述され、小さなデータセットでテストされたコードが、「動作しているように見える」ため、はるかに大きなデータセットですぐに使用されることがよくあります。その後、突然、修正に数秒しかかからない場合、実行に数時間かかるコードがあります。O(N²)アルゴは、しばらくは機能しているように見えますが、データが拡張しても機能しなくなったため、作成した人がやめてしまい、なぜ永遠に続くのか誰にもわかりません。
Andreas Magnusson

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()特定のフォーマットを生成することを意味します。
Martijn Pieters

1
@MartijnPietersそれを言及していただきありがとうございます。解決策を調整しました。bin()Pythonのバイナリ整数リテラル構文の生成を目的としたデバッグツールであることをどのようにして知っていますか?ドキュメントでそれを見つけることができませんでした。
Martin Thoma

2
ドキュメントから:結果は有効なPython式です。その目的は、Pythonの式を生成することであり、エンドユーザーの表現を生成することではありません。同じことが、にも適用されるoct()hex()
Martijn Pieters

4
その他の選択肢:幅を動的にするstr.zfill()場合は、代わりに、str.format()またはformat()動的な2番目の引数:'{0:0{1}b}'.format(x, n)またはを使用できますformat(b, '0{}b'.format(n))
Martijn Pieters

@MartijnPietersうわー、この入力をありがとうございました!これがフォーマットで可能であることを知りませんでした。ただし、私の現在の答えzfillは、動的な2番目の引数よりも読みやすく、理解しやすいと思うので、これはそのままにしておきます。
Martin Thoma、2015

38

参考として:

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

この関数は18446744073709551615、文字列として表されると同じ大きさの正の整数を変換できます'1111111111111111111111111111111111111111111111111111111111111111'

"{0:b}".format()またはほど便利ではないかもしれませんが、はるかに大きな整数を提供するように変更できますbin()


@GarethDavidsonこれはどのバージョンですか?これを明示的に述べることは、それをグーグルするときに、より大きな将来の利用になるかもしれません。
ウルフ

バージョン2.7だと思います。3.xではうまくいくとは思えない
Gareth Davidson

17

これを行う簡単な方法は、文字列形式を使用することです。このページを参照してください

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

そして、あなたがバイナリ文字列の固定長を持ちたいなら、これを使うことができます:

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

2の補数が必要な場合は、次の行を使用できます。

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

ここで、nはバイナリ文字列の幅です。



14

ラムダ付きワンライナー:

>>> 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 2017年

あなたがその0 :)を見たい場合は、交換することが可能'''0'、それは、任意の数のための主要な0が追加されます。
Aziz Alto

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()1つの値をフォーマットするだけではやり過ぎです。format()関数に直接進みますformat(n, 'b')。プレースホルダーを解析して、それを引数に一致させる必要はありません。
Martijn Pieters



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 **(桁-1)から2 **(桁-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 

2番目のバージョンは、O(N)ではなくO(N ^ 2)アルゴリズムのようなものになるため、明らかに高速ではありません。開発者が最後に追加のパスを実行することは、最初のループで追加の処理を実行するよりも遅いと考えたため、これがアプリケーションを(パフォーマンスに関して)強制終了するのを見てきました。修正後、実行時間は数日から数秒に短縮されました。
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"、 "")
sannerの少し

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'
2014年


3

numpy.binary_repr(num, width=None)

上記のドキュメントリンクの例:

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

入力数値が負で幅が指定されている場合、2の補数が返されます。

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

これは、通常の数学を使用するもう1つの方法です。ループはなく、再帰のみです。(単純なケース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))

数値のヘキサ10進数を計算するには

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

16までのすべてのバイナリを計算するには:

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

17までヘキサ10進数を計算するには

 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
そこで行ったことに説明を加えたいと思うかもしれません。
アートレス2017

1

行列演算を使用して10進数を2進数に変換する方法を見つけました。

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は入力10進データ、M2進数の順序です。bindataは、出力バイナリデータで、1行M列のバイナリマトリックスの形式です。


0

これは、継続的にループする単純な2進数から10進数へのコンバーターです。

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

    print(convertedNumber)

print("")

これは、OPが必要とするものの逆の順序です。彼らはintからbinaryを探しています。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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.