ブール論理
レッスン 03 では、論理演算子
and、or、notを含む演算子について学びました。このレッスンでは、真/偽の判定に焦点を当てます——これはコンピュータサイエンスで最も基本的な概念です。ブール論理はすべての条件文、ループ制御、権限チェックの基礎です。
1. ブール値:True と False
ブール値は 2 つしかありません:True と False です。これらはブール代数を創設した英国の数学者 George Boole にちなんで名付けられました。ブール代数は現代のコンピューティングの「0 と 1」の理論的基盤です。
print(True) # 出力:True
print(False) # 出力:False
print(type(True)) # <class 'bool'>
比較演算子はブール値を生成します:
print(5 > 3) # True
print(10 == 5) # False
print(7 <= 7) # True
print(3 != 3) # False
ブール値は数値でもある
Python では、True と False は実際には int のサブクラスです——True は 1、False は 0 と同等です:
print(True + True) # 2(True=1、2 つの True = 2)
print(True * 10) # 10
print(False * 100) # 0
True == 1 と False == 0 が成立しますが(したがって True + True は 2 になります)、決してこのように使わないでください。ブール値は論理判断のためのものであり、算術演算のためのものではありません。score + True のようなコードを書くと、読む人を混乱させます。
例:健康診断結果(難易度 ⭐)
# 比較演算子でブール値を生成
age = 25
height = 175
weight = 70
is_adult = age >= 18 # True
is_tall = height > 170 # True
is_heavy = weight > 80 # False
print(f"Adult: {is_adult}")
print(f"Tall: {is_tall}")
print(f"Overweight: {is_heavy}")
# ブール値を直接出力 — 値であってテキストではない
print(f"Adult AND Tall: {is_adult and is_tall}")
出力:
Adult: True
Tall: True
Overweight: False
Adult AND Tall: True
2. not:否定
not は「反転」を意味します——黒は白に、白は黒になります。
print(not True) # False
print(not False) # True
print(not (5 > 3)) # False(5>3 は True、否定されて False)
not は主に 2 つのシナリオで使用されます:
シナリオ 1:「条件を満たしていない」ことを確認
# 管理者ではない — バックエンドに入れない
is_admin = False
if not is_admin:
print("You do not have admin access.")
# 出力:You do not have admin access.
シナリオ 2:変数が空かどうかを確認
# ユーザーが名前を提供しなかったかどうかを確認
username = ""
if not username:
print("Username cannot be empty!")
# 出力:Username cannot be empty!
ここに Python の「暗黙のブール変換」のトリックがあります——空文字列 "" は条件チェックで False と同等です。したがって、username が空文字列の場合、not username は True になります。どの値が「falsy」かは後で説明します。
not は「否定」を意味します。コードでは、if not is_admin: は「管理者でない場合」と読みます。
3. and:両方が真でなければならない
and は「両方」を意味します——結果が True になるには両方の条件が真でなければなりません。どちらかが偽なら結果は False です。
| 左 | 右 | 結果 |
|---|---|---|
| True | True | True |
| True | False | False |
| False | True | False |
| False | False | False |
age = 22
has_id = True
# 両方の条件を満たす必要がある
can_buy_alcohol = age >= 18 and has_id
print(can_buy_alcohol) # True(年齢条件を満たし、ID も持っている)
# 別のシナリオ:クレジットカードの申し込みには年収 50 万以上 AND 信用スコア 600 以上が必要
income = 80 # 千単位
credit_score = 650
qualified = income >= 50 and credit_score >= 600
print(f"Credit card application: {qualified}") # True
例:ログインチェック(難易度 ⭐)
# ログインをシミュレート — 正しいユーザー名 AND 正しいパスワード
username_correct = True
password_correct = False
can_login = username_correct and password_correct
print(f"Login result: {can_login}") # False — パスワードが間違っている
# さらにレイヤーを追加:アカウントがロックされていないこと
account_locked = True
can_login = username_correct and password_correct and not account_locked
print(f"Final result: {can_login}") # False — アカウントがロックされている
出力:
Login result: False
Final result: False
4. or:少なくとも 1 つが真
or は「どちらか」を意味します——少なくとも 1 つの条件が真なら結果は True です。両方が偽の場合のみ結果は False です。
| 左 | 右 | 結果 |
|---|---|---|
| True | True | True |
| True | False | True |
| False | True | True |
| False | False | False |
# 週末か祝日は休める
is_weekend = True
is_holiday = False
can_rest = is_weekend or is_holiday
print(can_rest) # True(週末なので)
# 地下鉄のセキュリティ:水か飲み物を持っている場合、チェックが必要
has_water = True
has_drink = False
need_check = has_water or has_drink
print(f"Security check needed: {need_check}") # True
練習:完全な真理値表の確認
# コードで真理値表を確認 — and と or のすべての組み合わせ
a = True
b = True
print(f"{a} and {b} = {a and b}")
print(f"{a} or {b} = {a or b}")
a = True
b = False
print(f"{a} and {b} = {a and b}")
print(f"{a} or {b} = {a or b}")
a = False
b = True
print(f"{a} and {b} = {a and b}")
print(f"{a} or {b} = {a or b}")
a = False
b = False
print(f"{a} and {b} = {a and b}")
print(f"{a} or {b} = {a or b}")
出力:
True and True = True
True or True = True
True and False = False
True or False = True
False and True = False
False or True = True
False and False = False
False or False = False
5. ショートサーキット評価
レッスン 03 でこれについて触れましたが、非常に重要なのでさらに深く掘り下げます。Python の論理演算子は、結果が確定した時点で評価を停止し、残りの式を実行しません。
and のショートサーキット:左辺が False → 右辺は実行されない
def check_right():
print("-> check_right was called!")
return True
print("False and check_right():")
result = False and check_right() # check_right は実行されない
print(f"Result: {result}\n")
print("True and check_right():")
result = True and check_right() # check_right は実行される
print(f"Result: {result}")
出力:
False and check_right():
Result: False
True and check_right():
-> check_right was called!
Result: True
or のショートサーキット:左辺が True → 右辺は実行されない
print("True or check_right():")
result = True or check_right() # check_right は実行されない
print(f"Result: {result}")
ショートサーキット評価の古典的な用途
1. 安全なアクセス:None エラーの防止
# ユーザーが None の可能性があるとする(ユーザーが存在しない)
user = None
# user.get("name") はエラーになる — None に get メソッドはない
# ショートサーキットを使って保護:
name = user and user.get("name")
print(name) # None — user は falsy、ショートサーキット、user.get() は呼ばれない
# ユーザーが存在する場合:
user = {"name": "Xiao Ming"}
name = user and user.get("name")
print(name) # Xiao Ming
2. デフォルト値の設定
# ユーザーが名前を入力しなかった場合、デフォルトを使用
user_input = "" # 空文字列(falsy)
name = user_input or "guest"
print(f"Welcome, {name}") # Welcome, guest
user_input = "Zhang San"
name = user_input or "guest"
print(f"Welcome, {name}") # Welcome, Zhang San
user_input or "default" パターンは非常に Python らしいです——左辺が falsy(空文字列)なら右辺を使用し、truthy(内容がある)なら左辺を使用します。これは or のショートサーキット動作を活用しています。
6. Truthy と Falsy の値
Python では、任意の値を条件の中でブール値として使用できます。一部の値は「falsy」と見なされ、それ以外はすべて「truthy」です。
よくある Falsy の値
# これらの値は条件の中で False と同等
print(bool(False)) # False — ブール値の false
print(bool(0)) # False — ゼロ
print(bool(0.0)) # False — 浮動小数点数のゼロ
print(bool("")) # False — 空文字列
print(bool([])) # False — 空のリスト(後で説明)
print(bool(None)) # False — null 値
それ以外はすべて truthy です:
print(bool(1)) # True — ゼロ以外の数値
print(bool(-5)) # True — 負の数も truthy!
print(bool("Python")) # True — 空でない文字列
print(bool(" ")) # True — スペースは文字であり、空でないので truthy
print(bool([1, 2])) # True — 空でないリスト
-5 と " "(スペース)はどちらも truthy です。これは驚くかもしれません。-5 はゼロ以外の整数なので truthy です。スペースは文字であり、文字列が空でないので truthy です。空文字列 "" だけが falsy です。
真偽値を利用してコードを簡潔に
# 推奨しない(冗長)
name = "Xiao Ming"
if name != "":
print(f"Hello, {name}")
# 推奨(簡潔)
name = "Xiao Ming"
if name:
print(f"Hello, {name}")
# 推奨しない
score = 85
if score != 0:
print(f"Score: {score}")
# 推奨
score = 85
if score:
print(f"Score: {score}")
if name: は if name != "": よりも「Python らしい」です。ただし、使いすぎに注意してください——if score: は score=0 のとき実行されません。「スコアが 0」と「スコアがない」を区別する必要がある場合は、is not None を使用してください。
7. is と is not:同一性比較
is は 2 つの変数が同じオブジェクト(メモリ上の同じ領域)を指しているかどうかを比較し、値が等しいかどうかは比較しません。レッスン 03 で触れましたが、ここでさらに例を示します。
# == は値を比較、is は同一性を比較
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True — 同じ値
print(a is b) # False — しかし同じリストオブジェクトではない
print(a is c) # True — c は a、同じリストを指す
# 小整数のキャッシュ(Python 内部の最適化)
x = 256
y = 256
print(x is y) # True の場合がある — 小整数はキャッシュされる
x = 1000
y = 1000
print(x is y) # False の場合がある — 大きな整数はキャッシュされない
is を整数や文字列に使わないでください。 小整数は Python の内部最適化により is で True を返すことがありますが、これは実装の詳細であり信頼できません。値の比較には常に == を使用してください。
正しい使用方法:None のチェック
Python コミュニティには慣習があります——値が None かどうかをチェックするときは、常に is を使い、== は使わない:
# 正しい方法
result = None
if result is None:
print("No result")
# 推奨しない
if result == None:
print("No result")
よくあるユースケース
- 権限制御:
is_admin or (is_logged_in and has_permission)—— 複数の条件を組み合わせてユーザーができることを決定 - 入力検証:
username and password—— ユーザーが両方を提供したかどうかを確認 - オプションパラメータのデフォルト:
timeout or 30—— タイムアウトが設定されていない場合、デフォルトの 30 秒を使用 - 安全なアクセスチェーン:
user and user.address and user.address.city—— レイヤーごとの安全なアクセス。いずれかの falsy な段階でショートサーキット - トグル制御:
is_enabled and is_connected—— 操作を続行するには両方の条件を満たす必要がある
❓ よくある質問
True と "True" の違いは何ですか?True(引用符なし)はブール値です。"True"(引用符あり)は文字列です。これらは異なります:type(True) は <class 'bool'>、type("True") は <class 'str'> です。条件では、if "True": は常に True(空でない文字列は truthy)、if "False": も常に True(これも空でない)です。したがって、条件の中でブール値を引用符で囲まないでください。is と == はいつ使い分ければよいですか?== を使います。is が慣習的に使われるのは 1 つのシナリオだけです——None のチェック:if result is None:。他のすべての値比較には == を使います。覚えておいてください:== は「値」を比較し、is は「同一性」を比較します。and/or のショートサーキット評価にはどのような落とし穴がありますか?and や or の右側に関数呼び出しを置くと、ショートサーキットにより実行されない可能性があり、スキップされたことに気づきません。その関数に副作用(ログ記録、メール送信、カウンター更新)がある場合、ショートサーキットは一貫性のない動作を引き起こす可能性があります。良い習慣:右辺の式に副作用がある場合は、ショートサーキットに頼らず、別々に記述してください。not not "hello" は True を返すのですか?not "hello" は最初に "hello" をブール値として評価し(空でない文字列は truthy)、否定して False を取得します。次に not not "hello" は False を再度否定して True を取得します。つまり not not x は bool(x) と同等であり、x をブール値に変換します。しかしこのパターンは一般的ではありません。明確さのために bool(x) を直接使用してください。📖 まとめ
- ブール値は 2 つだけ:
TrueとFalse。これらはintのサブクラス(True=1、False=0)ですが、算術演算には使いません notは否定する:真は偽に、偽は真にandは両方が真である必要があるorは少なくとも 1 つが真であればよい- Python の falsy な値:
False、0、0.0、""、[]、None—— それ以外はすべて truthy - ショートサーキット:
andは左辺が偽なら右辺を実行しない。orは左辺が真なら右辺を実行しない - ショートサーキットにより 2 つの古典的パターンが可能に:「安全なアクセス」と「デフォルト値」
isは同一性を比較、==は値を比較。Noneのチェックにはisを使用
📝 練習問題
-
初級(難易度 ⭐):次の式の値を予測し、確認してください:
not (10 > 5)True and False or Truenot False and True(5 > 3) or (2 > 10) and (8 == 8)—— ヒント:優先順位に注意——andはorより優先順位が高い
-
中級(難易度 ⭐⭐):ユーザーの入力文字列を検証するコードを書いてください:
- 入力が空の場合、「入力は空にできません」と出力
- 入力がすべてスペースの場合も、「入力は空にできません」として扱う(ヒント:
strip()を使用) - 入力の長さが 6 未満の場合、「入力は少なくとも 6 文字必要です」と出力
- それ以外の場合、「入力は有効です」と出力
-
上級(難易度 ⭐⭐⭐):「3 桁の数値チェッカー」を書いてください。3 桁の数値
num(例:153)が与えられたとき、以下を判定します:- 偶数ですか?(
%を使用) - 3 と 5 の両方で割り切れますか?
- 回文数ですか?(百の位と一の位が等しい、例:121、353)
- 上記の条件のうちいくつを満たしていますか?その数を出力してください。
すべてのチェックにブール式のみを使用してください。if 文は使いません(次のレッスンで学びます)。
- 偶数ですか?(



