pythonのブール演算はブール値を返さない

## はじめに
皆さんは次のコードの出力結果を答えられますか？

```python3:question_1.py
print('penguin' and 'PENGUIN')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342285/194f2ac9-817a-5ffc-597c-a952550d6fdc.png)


答えが ```PENGUIN``` とならなかった方は本記事に目を通されると良いかもしれません。

## Pythonにおけるオブジェクトの評価
まず簡単にPythonのオブジェクトについて復習しておきましょう。
Python では全てのオブジェクトが True か False と評価することができます。
特にFalseと評価されるオブジェクトは以下に絞られます(参考文献より引用)。

* None
* False
* 数値型の0 (int型の0やfloat型の0.0、複素数型の0jなど)
* 文字列やリスト、辞書、集合などのコンテナオブジェクトの空オブジェクト
* メソッド \_\_bool\_\_() がFalseを返すオブジェクト
* メソッド \_\_bool\_\_() を定義しておらず、メソッド \_\_len\_\_() が0を返すオブジェクト

よく使うのは上記4つなので覚えておくと便利です。
従って、Pythonでは以下のように条件式に直接オブジェクトを代入して評価することが可能です。

```python3:eval_obj.py
penguin_list = ['Emperor', 'Humboldt', 'Adelie']
if (penguin_list):
    print("ペンギン祭り")
else:
    print("ペンギンは絶滅しました")
# 実行結果 : ペンギン祭り
```

## or
orは論理和と呼ばれ、```x or y``` としたときに x または y が真のときには真を返し、そうでないときは偽を返すのが一般的です。
先ほど見たように、Pythonではオブジェクトは True または False で評価されます。
よって次のような評価が可能です。

```python3:or_peugin.py
print('penguin' or None)
```

さて、通常であれば上記は True を返しそうに思いますが、PythonではTrueを返しません。
結果は以下のようになります。

```:出力結果
penguin
```
実はPythonにおいてx or y は、x の評価が True なら x を、そうでなければ y を返します。
要するに、__通常の論理和演算と同様に考え、値が確定した時点のオブジェクトを返します。__
いくつかのサンプルを記しておきます。

```python3:or_sample.py
print('Emperor' or 'Humboldt')
# 出力結果：Emperor
print('Humboldt' or 'Emperor')
# 出力結果：Humboldt
print('penguin' or 0)
# 出力結果：penguin
print(False or 'penguin')
# 出力結果：penguin
print(0 or False)
# 出力結果：False
print(False or 0)
# 出力結果：0
```

## and
and は論理積と呼ばれ、```x and y``` としたときに x と y がともに真のときには真を返し、そうでないときは偽を返すのが一般的です。
しかし論理積もPythonでは戻り値はbool値ではありません。
Pythonにおいてx and y は、 x の評価が False なら x を、それ以外の場合は y を返します。
要するに、__通常の論理積演算と同様に考え、値が確定した時点のオブジェクトを返します。__
いくつかのサンプルを記しておきます。

```python3:and_sample.py
print('Emperor' and 'Humboldt')
# 出力結果：Humboldt
print('Humboldt' and 'Emperor')
# 出力結果：Emperor
print('penguin' and 0)
# 出力結果：0
print(False and 'penguin')
# 出力結果：False
print(0 and False)
# 出力結果：0
print(False and 0)
# 出力結果：False
```

## 最後に
昨今の機械学習ブームとpythonがシンプルな文法であることから、なんとなくでpythonを扱っている方も少なくないと思います(自分含め)。
しかしきちんと勉強すると面白いものですし、なんとなくな理解だと思わぬバグや想定外の挙動を起こすこともあるでしょう。
昨日までの筆者も「論理演算なんてbool値を返すに決まっとるやんけ(鼻ﾎｼﾞ)」だったので、もしかしたら近い将来とんでもないクリーチャを生み出し世に放っていたのかもしれません。
参考文献にも挙げていますが、今年出版された [Python実践入門](https://www.amazon.co.jp/Python%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-%E8%A8%80%E8%AA%9E%E3%81%AE%E5%8A%9B%E3%82%92%E5%BC%95%E3%81%8D%E5%87%BA%E3%81%97%E3%80%81%E9%96%8B%E7%99%BA%E5%8A%B9%E7%8E%87%E3%82%92%E9%AB%98%E3%82%81%E3%82%8B-WEB-PRESS-plus%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/429711111X/ref=sr_1_1?dchild=1&hvadid=386600561258&hvdev=c&jp-ad-ap=0&keywords=python%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80&qid=1594634033&sr=8-1&tag=yahhyd-22) はPythonを学ぶにうってつけの書籍です。
是非皆さんもこの機会に「脱☆なんとなくPython」をしてみましょう！


## 参考文献
- [Python実践入門](https://www.amazon.co.jp/Python%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-%E8%A8%80%E8%AA%9E%E3%81%AE%E5%8A%9B%E3%82%92%E5%BC%95%E3%81%8D%E5%87%BA%E3%81%97%E3%80%81%E9%96%8B%E7%99%BA%E5%8A%B9%E7%8E%87%E3%82%92%E9%AB%98%E3%82%81%E3%82%8B-WEB-PRESS-plus%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/429711111X/ref=sr_1_1?dchild=1&hvadid=386600561258&hvdev=c&jp-ad-ap=0&keywords=python%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80&qid=1594634033&sr=8-1&tag=yahhyd-22)