Pythonでバイナリに変換して先行ゼロを保持する


154

Pythonのbin()関数を使用して整数をバイナリに変換しようとしています。ただし、実際に必要な先行ゼロは常に削除されるため、結果は常に8ビットになります。

例:

bin(1) -> 0b1

# What I would like:
bin(1) -> 0b00000001

これを行う方法はありますか?


参照:Python int to binary?、特にnビット表現での私の答え。全く同じではありませんが、私は私の質問を探してこの質問に来ました...
Martin Thoma

回答:


218

format()関数を使用します

>>> format(14, '#010b')
'0b00001110'

format()この関数は、単純に以下の入力フォーマットフォーマット仕様のミニ言語を。これ#により、フォーマットに0b接頭辞が含まれ、010サイズによって出力が10文字幅に収まるように0パディングされます。0b接頭辞には2文字、2進数には残りの8文字。

これは最もコンパクトで直接的なオプションです。

結果をより大きな文字列に入れる場合は、フォーマットされた文字列リテラル(3.6+)を使用するかstr.format()format()関数の2番目の引数をプレースホルダーのコロンの後に使用します{:..}

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

3
まさに私が探していたもので、このフォーマットは私にとって本当に役に立ちます。私はビット操作の学習を始め、Pythonでの数値のビットフォーマットを探していました。これを見つけた。ありがとうございました。
Kratostoical 2017

うまくいきます。ただし、少しかさばることがあります。format(192,'08b')+'.'+format(0,'08b')+'.'+format(2,'08b')+'.'+format(33,'08b') 11000000.00000000.00000010.00100001

@ tjt263:そのため、より大きな文字列に結果を配置する場合は、フォーマットされた文字列リテラル(3.6+)を使用するかstr.format()、プレースホルダーのコロンの後にformat()関数の2番目の引数を使用して配置することを明示します{:..}
Martijn Pieters

1
@ tjt263:たとえばを使用しますf"{192:08b}.{0:08b}.{2:08b}.{33:08b}"
Martijn Pieters

非常に素晴らしい。説明だけでそれが何を意味するのかは知りませんでした。しかし、今あなたの例を見たので、おそらくそれを決して忘れません。乾杯。

115
>>> '{:08b}'.format(1)
'00000001'

参照:フォーマット仕様のミニ言語


Python 2.6以前の:場合、前に位置引数識別子を省略できないため、次のように使用します

>>> '{0:08b}'.format(1)
'00000001'      

3
str.format()いつformat()行うかはここで使用する必要はありません。0bプレフィックスがありません。
Martijn Pieters

2
@MartijnPietersは、一度に複数の変数を実行できるためstr.formatよりも柔軟性がありformat()ます。そのformat機能が存在することすら忘れてしまいます。確かに、この場合は完全に適切です。
Mark Ransom 2013年

1
@MarkRansom:正確には、要素をstr.format()1つだけ使用して{}他のテキスト使用せず、文字列テンプレートを使用せず1つの値をフォーマットします。その場合はを使用してくださいformat()。:-)
Martijn Pieters


9

文字列形式のミニ言語を使用できます。

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

2
同じフォーマット言語を使用して、プレフィックスを含めることができます。を使用し#ます。もありformat()ます。これにより、完全な文字列テンプレートを実行する必要がなくなります。
Martijn Pieters

2

Pythonを使用する場合>= 3.6、最もクリーンな方法は、文字列フォーマットでf-stringsを使用することです。

>>> var = 23
>>> f"{var:#010b}"
'0b00010111'

説明:

  • var フォーマットする変数
  • : この後のすべてがフォーマット指定子です
  • #代替形式を使用(0b接頭辞を追加)
  • 0 ゼロで埋める
  • 10全長が10になるようにパッドします(これにはの2文字が含まれます0b
  • b 数値にバイナリ表現を使用する

いいえ、それは最もクリーンではありません。単一のプレースホルダーだけでなく、文字列をより多く使用する場合を除きます。それ以外の場合は、意図がはるかによくformat(var, "#010b")伝達されます。ただし、これは最速のオプションです。しかし、あなたが知っていることはすでにわかっています。私があなたが私の回答に投稿したものすべてをすでにカバーしているからです
Martijn Pieters

1

シンプルなワンライナーが必要な場合もあります。

binary = ''.join(['{0:08b}'.format(ord(x)) for x in input])

Python 3


1
[ ]必要ないことに注意してください- join()ジェネレータ式を受け入れます。''.join('{0:08b}'.format(ord(x)) for x in input)
Christoph Burschka

@ChristophBurschka str.join()は、2つのパスを作成する必要があるため、結合する前に、ジェネレーターの入力が最初にリストに変換されることに注意してください。これはパフォーマンスに少し負荷がかかりますが、実際には、ジェネレータ式ではなくリスト内包を渡す方が適切です。彼らがルールの例外であるなら、それは一つです。
Martijn Pieters

-1

あなたはこのようなものを使うことができます

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

2
コードスニペットには、少なくともコードブロックを使用してください。そして、本当に良い答えにしたい場合は、なぜこのソリューションがOPの質問を解決するのかについてのコメントも追加してください。
β.εηοιτ.βε

可変幅を追加するためだけに、別の文字列フォーマットスタイルを使用する必要はありません。ちょうど別のプレースホルダを追加します"{:0{l}b}".format(num, l=length)
マルタインピータース

-1

Python構文のrjust文字列メソッドを使用できます:string.rjust(length、fillchar)fillcharはオプションです

そしてあなたの質問のためにあなたはこのように書きます

'0b'+ '1'.rjust(8,'0)

したがって、「0b00000001」になります


構文エラーがあります。しかし、さらに重要なことは、intをテキストのバイナリ表現に変換することに関する質問にはまったく答えません。で始まることすらありませんint
ティエリーラトゥイユ

-3

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)は、 2月にxを '02'として返します。


1
zfillの問題は、バイナリ文字列を文字列のように扱い、バイナリ 'b'インジケータの前にゼロを追加することです。たとえば bin(14)bin(14).zfill(8) `'0b1110'` を与え、 `'0b00001110'` を 与えます
Shaun
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.