はじめに
今回は、Pythonの演算子「&」と「and」の使い分けについて解説します。
Pythonの導入や基本操作が行えることを前提で進めます。
↓前提知識はこちらをご覧ください↓


結論だけ言うと…
・if文の条件分岐には「and」を使う
・ビット関係の処理には「&」を使う
です。
「and」と「&」の違い
「and」と「&」は下記
・「and」 → 論理演算子
・「&」 → ビット演算子
この2つが違いです。
論理演算子の「and」について
論理演算子は “通常” の情報が2つある場合の処理です。
主に「2つ以上の条件があるif文」で使われます。

論理演算の中で「and」は両方が0以外であれば、右側の値を出力する処理になります。
↓この場合、「True and True」のときだけ右側の「Ture」が出力されます。

ちなみに「True」と「False」はbool型という情報です。
なので… Ture → 1、False → 0の入力になります。
そして、0が入った処理はすべて「False」を返すようになりました。

では、1以上の数字を打ち込むと「後ろの数字」が出力されます。

片側が「マイナス」や「小数でも」後ろの数字が出力されます。

つまりandで「False(0)」になるのは、どちらかが「0」に完全に一致する時だけです。

以上が、論理演算子の「and」についての解説です。
ビット演算の「&」について
ビット演算子は “ビット型” の情報が2つある場合の処理です。
ビットについて、凄く大雑把に解説すると… 「2進数データ」になります。

そして、ビット演算子を使うと…
用意した2つの2進数データを組み合わせて別の2進数データが作れます。


「0b」は、これ以降に書く数字が2進数ですとパソコンに伝えるための記号です。
「&」はそのビット演算子の1つ。
2つのビットが立ってる所を「1」にする処理になります。

イメージとしては下図の通り。
これが、ビット演算子「&」の効果です。

↓ビットの詳細や他のビット演算子はこちらで解説。

「and」の使い道
andは「if文」に使うのに向いてます。
理由は下記。
・文字のif文は「and」でしか作れない
・2つ以上の条件があるif文が「&」を使わない方が良い
この2つについて解説していきます。
文字条件のif文は「and」でしか作れない
「if &」の形だと、文字用のデータ型「str」が使えません。

ですが「if and」を使うと「str型」での条件一致が使えます。

このように、文字条件のif文は「and」でしか作れません。
これが、一番のif文では「and」を使う事をおすすめする理由です。

if文に「&」を使う癖ができてしまうと…
うっかり文字型で動かないエラーを引き起こす可能性があります。
なので、if文は基本「and」を使う事をおすすめします。
2つ以上の条件があるif文が「and」と「&」の両方で動く理由
2つ以上の条件があるif文は「and」と「&」の両方で一応動きます。
こちらの作例として、まず1つ目の条件「1 == 1」などを作成。
すると、出力結果が下記のようになります。
・1 == 1 → Ture
・1 == 0 → False
・0 == 1 → False
・0 == 0 → Ture


「==」は右と左の “値” が同じ場合、Tureを返す処理です。
値の一致なので「1」と「1.0」でも可(詳細)
なので… 2つ以上の条件を()を使って and で繋ぐと…
両方が「Ture」の時に「Ture」を返すような処理を作れます。

これが、2つ以上の条件があるときの「and」の挙動です。

そして if 文は「Ture」が帰って来た時に処理を実行するので…
2つの条件が一致した時に実行する「if」文が使えます。

これが一般的な「and」の用途ですが…
これは「&」でも使えます。


こうして「and」と「&」の違いが分からず…
混乱する難民が登場する。
なぜ「&」でも動くかを説明していきます。
まずTrueは整数のint型に変換すると「1」でFalseは「0」になる事を思い出してください。

そして、bin()は整数を2進数(ビット)に変換する処理です。
bin(1)は「0b1」 になり、bin(0)は「0b0」になります。


「0b」は2進数表記ですよとアピールするための記号です。
なので情報的には「1」と「0」だけになります。
ビット演算子の「&」は、2つのビットが立ってる所を「1」にする処理です。
なので、10進数の「1」と「0」と、ビット演算の「0b1」と「0b0」では
偶然の一致に近い理由で、同じ挙動をする処理になります。

これが、2つ以上の条件分岐は「and」と「&」の2つで動く理由です。
2つ以上の条件があるif文が「&」を使わない方が良い理由
2つ以上の条件分岐は「&」を使うとやや不安定になります。
たとえば「0b1010001」と「0b011001」を「&」で繋ぐと…
2進数で「0b10001」が帰り、10進数では「17」変えります。

ちなみに、0b1010001は10進数で「81」になります。
0b011001は10進数で「49」になります。


「0b1010001」と「0b0110001」は
「81」と「49」に置き換えてokです。
これは、ビット演算の「&」の挙動で見た場合…
ビットが立ってる所が一致するところだけ「1」を返した結果です。

「81」は2進数で0b1010001になります。
「49」は2進数で0b0110001になります。
なので、「&」で下図のような結果になりました。

そして、出力結果の「17」は1以上。
つまり、if文に使うと0以外は「Ture」に変換されるので、中の処理が実行されます。

ちなみに、「and」でも「1」以上の整数を入れればTureになります。


なので「and」と「&」を使う場合、1以上の整数で条件を取るとTureになる。
…と思いたい所ですが、
「&」には、思わぬ落とし穴にがあります。
ではTureを狙って「81」と「46」を入れると…
結果は「False」でif文が実行されなくなります。

何が起こったかというと…
2つの数字のビットが立った位置の問題で、このようなエラーが発生しました。

こちら「and」だと、条件が両方とも「0」以外なので、正しくif文が実行されます。


このように「&」を条件分岐などで使うとやや挙動が不安定です。
そして、バグの原因になる可能性があるので、おすすめしません。
以上が、2つ以上の条件があるif文が「&」を使わない方が良い理由です。
「&」の使い道
&は「ビット演算」に使うためにあります。
既に実行しましたが… 2つ以上の2進数を用意。
「&」を使えば、両方のビットが立ってる時に「1」を出力します。

下図のような計算がしたい場合、ビット演算子の「&」を使う必要が出てきます。

「and」はビット演算ができない
ビット演算には「and」が使えません。
andは両方の値が「0」以外の時に、右側の情報を返す処理になります。
なので、ビット演算が行われません。

右側の「49」が帰って終わります。

なので、ビット演算をしたい場合は「&」を使う必要があります。

ようするに、条件分岐は「and」で、ビット処理は「&」
まとめ
今回は、Pythonの演算子「and」と「&」の使い分けについて解説しました。
・「and」は2つの値が「0」以外なら、右側の値を返す処理
・「and」はif文に使うのがおすすめ
・「&」はビット演算に使うための演算子
・if文に「&」を使うと文字型などが使えないエラーの原因になる
・ビット演算に「and」を使っても、ビット演算の処理は行われない
また、他にもプログラムについて解説してます。


ぜひ、こちらもご覧ください。
コメント