自分が最初におもっていた仕様
誤解1 or
, and
は基本的に引数はbool
型で返り値はbool
型でbool
型
たとえば,
0<x<10 or x%2==0
という式があったら, x=14
だとしたら
0<x<10
はFalse
になって, x%2==0
はTrue
となって
False or True
が計算されてTrue
になるみたいな感じで頭の中で解釈していた。
誤解2 引数がbool
型じゃない場合は, None
の場合はFalse
になって, それ以外の場合はTrue
となる
たとえば,
if os.getenv('OPENAI_API_KEY') :
とかくと, APIキーが設定されていず, None
となるとき, False
として解釈される.
os.getenv('OPENAI_API_KEY')
があるときTrue
と解釈される.
誤解2の解消
None
以外でも以下のものはFalse
と評価される。
「偽」と評価されるもの
以下のオブジェクトはFalse
と評価される
None
False
- 数値のゼロ
-
0
(整数) -
0.0
(浮動小数点数) -
0j
(複素数)
-
- 空のシーケンスおよびコレクション
-
''
(空文字列) -
[]
(空リスト) -
()
(空タプル) -
set()
(空セット) -
frozenset()
(空フローズンセット) -
{}
(空辞書)
-
- 空の範囲
range(0)
「真」と評価されるもの
上記以外のすべてのオブジェクトはTrue
と評価される。
実例
以下の例では、さまざまなオブジェクトが「真」と評価されるか「偽」と評価されるかを確認できます:
# 偽と評価されるもの
print(bool(None)) # False
print(bool(False)) # False
print(bool(0)) # False
print(bool(0.0)) # False
print(bool(0j)) # False
print(bool('')) # False
print(bool([])) # False
print(bool(())) # False
print(bool(set())) # False
print(bool(frozenset())) # False
print(bool({})) # False
print(bool(range(0))) # False
# 真と評価されるもの
print(bool(True)) # True
print(bool(1)) # True
print(bool(-1)) # True
print(bool(3.14)) # True
print(bool(-3.14)) # True
print(bool(1j)) # True
print(bool(-1j)) # True
print(bool('Hello')) # True
print(bool([1, 2, 3])) # True
print(bool((1, 2, 3))) # True
print(bool({1, 2, 3})) # True
print(bool(frozenset({1, 2, 3}))) # True
print(bool({'key': 'value'})) # True
print(bool(range(1, 10))) # True
誤解1の解消
誤解1している状態だと
print(None and "default") # False
print(0 and "fallback") # False
print([] or "empty list") # True
print("value" or "default") # True
print(1 or 0) # True
print(True and False) # False
みたいな結果になってしまう。
or
演算子は、左から右に評価し、最初にTrue
と評価される値を返し, すべてがFalse
の場合は、最後の値を返す
and
演算子は、左から右に評価し、最初にFalse
と評価される値を返し,すべてがTrue
の場合は、最後の値を返す
という仕様だ。
誤解1している状態だと
print(None and "default") # None
print(0 and "fallback") # 0
print([] or "empty list") # "empty list"
print("value" or "default") # "value"
print(1 or 0) # 1
print(True and False) # False
となる。
この仕様を利用すると以下のような3項演算子をシンプルにかける
self.api_key = api_key if api_key else os.getenv('OPENAI_API_KEY')
# の代わりに
self.api_key = api_key or os.getenv('OPENAI_API_KEY')
# とかける.