ブール論理

レッスン 03 では、論理演算子 andornot を含む演算子について学びました。このレッスンでは、真/偽の判定に焦点を当てます——これはコンピュータサイエンスで最も基本的な概念です。ブール論理はすべての条件文、ループ制御、権限チェックの基礎です。


1. ブール値:True と False

ブール値は 2 つしかありません:TrueFalse です。これらはブール代数を創設した英国の数学者 George Boole にちなんで名付けられました。ブール代数は現代のコンピューティングの「0 と 1」の理論的基盤です。

PYTHON
print(True)    # 出力:True
print(False)   # 出力:False
print(type(True))   # <class 'bool'>

比較演算子はブール値を生成します:

PYTHON
print(5 > 3)      # True
print(10 == 5)    # False
print(7 <= 7)     # True
print(3 != 3)     # False

ブール値は数値でもある

Python では、TrueFalse は実際には int のサブクラスです——True1False0 と同等です:

PYTHON
print(True + True)      # 2(True=1、2 つの True = 2)
print(True * 10)        # 10
print(False * 100)      # 0
⚠️ 注意:Python では True == 1False == 0 が成立しますが(したがって True + True は 2 になります)、決してこのように使わないでください。ブール値は論理判断のためのものであり、算術演算のためのものではありません。score + True のようなコードを書くと、読む人を混乱させます。

例:健康診断結果(難易度 ⭐)

PYTHON
# 比較演算子でブール値を生成
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}")
▶ 試してみよう

出力:

TEXT
Adult: True
Tall: True
Overweight: False
Adult AND Tall: True

2. not:否定

not は「反転」を意味します——黒は白に、白は黒になります。

PYTHON
print(not True)      # False
print(not False)     # True
print(not (5 > 3))   # False(5>3 は True、否定されて False)

not は主に 2 つのシナリオで使用されます:

シナリオ 1:「条件を満たしていない」ことを確認

PYTHON
# 管理者ではない — バックエンドに入れない
is_admin = False
if not is_admin:
    print("You do not have admin access.")
# 出力:You do not have admin access.

シナリオ 2:変数が空かどうかを確認

PYTHON
# ユーザーが名前を提供しなかったかどうかを確認
username = ""
if not username:
    print("Username cannot be empty!")
# 出力:Username cannot be empty!

ここに Python の「暗黙のブール変換」のトリックがあります——空文字列 "" は条件チェックで False と同等です。したがって、username が空文字列の場合、not usernameTrue になります。どの値が「falsy」かは後で説明します。

💡 ヒント:not は「否定」を意味します。コードでは、if not is_admin: は「管理者でない場合」と読みます。


3. and:両方が真でなければならない

and は「両方」を意味します——結果が True になるには両方の条件が真でなければなりません。どちらかが偽なら結果は False です。

結果
True True True
True False False
False True False
False False False
PYTHON
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

例:ログインチェック(難易度 ⭐)

PYTHON
# ログインをシミュレート — 正しいユーザー名 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 — アカウントがロックされている
▶ 試してみよう

出力:

TEXT
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
PYTHON
# 週末か祝日は休める
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

練習:完全な真理値表の確認

PYTHON
# コードで真理値表を確認 — 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}")

出力:

TEXT
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 → 右辺は実行されない

PYTHON
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}")

出力:

TEXT
False and check_right():
Result: False

True and check_right():
-> check_right was called!
Result: True

or のショートサーキット:左辺が True → 右辺は実行されない

PYTHON
print("True or check_right():")
result = True or check_right()    # check_right は実行されない
print(f"Result: {result}")

ショートサーキット評価の古典的な用途

1. 安全なアクセス:None エラーの防止

PYTHON
# ユーザーが 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. デフォルト値の設定

PYTHON
# ユーザーが名前を入力しなかった場合、デフォルトを使用
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 の値

PYTHON
# これらの値は条件の中で 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 です:

PYTHON
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 です。

真偽値を利用してコードを簡潔に

PYTHON
# 推奨しない(冗長)
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 で触れましたが、ここでさらに例を示します。

PYTHON
# == は値を比較、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 の内部最適化により isTrue を返すことがありますが、これは実装の詳細であり信頼できません。値の比較には常に == を使用してください。

正しい使用方法:None のチェック

Python コミュニティには慣習があります——値が None かどうかをチェックするときは、常に is を使い、== は使わない:

PYTHON
# 正しい方法
result = None
if result is None:
    print("No result")

# 推奨しない
if result == None:
    print("No result")

よくあるユースケース


❓ よくある質問

Q True"True" の違いは何ですか?
A True(引用符なし)はブール値です。"True"(引用符あり)は文字列です。これらは異なります:type(True)<class 'bool'>type("True")<class 'str'> です。条件では、if "True": は常に True(空でない文字列は truthy)、if "False": も常に True(これも空でない)です。したがって、条件の中でブール値を引用符で囲まないでください。
Q is== はいつ使い分ければよいですか?
A 99% のケースで == を使います。is が慣習的に使われるのは 1 つのシナリオだけです——None のチェック:if result is None:。他のすべての値比較には == を使います。覚えておいてください:== は「値」を比較し、is は「同一性」を比較します。
Q andor のショートサーキット評価にはどのような落とし穴がありますか?
A 最も一般的な落とし穴は関数呼び出しに関するものです。andor の右側に関数呼び出しを置くと、ショートサーキットにより実行されない可能性があり、スキップされたことに気づきません。その関数に副作用(ログ記録、メール送信、カウンター更新)がある場合、ショートサーキットは一貫性のない動作を引き起こす可能性があります。良い習慣:右辺の式に副作用がある場合は、ショートサーキットに頼らず、別々に記述してください。
Q なぜ not not "hello" は True を返すのですか?
A not "hello" は最初に "hello" をブール値として評価し(空でない文字列は truthy)、否定して False を取得します。次に not not "hello"False を再度否定して True を取得します。つまり not not xbool(x) と同等であり、x をブール値に変換します。しかしこのパターンは一般的ではありません。明確さのために bool(x) を直接使用してください。

📖 まとめ

  • ブール値は 2 つだけ:TrueFalse。これらは int のサブクラス(True=1False=0)ですが、算術演算には使いません
  • not は否定する:真は偽に、偽は真に
  • and は両方が真である必要がある
  • or は少なくとも 1 つが真であればよい
  • Python の falsy な値:False00.0""[]None —— それ以外はすべて truthy
  • ショートサーキット:and は左辺が偽なら右辺を実行しない。or は左辺が真なら右辺を実行しない
  • ショートサーキットにより 2 つの古典的パターンが可能に:「安全なアクセス」と「デフォルト値」
  • is は同一性を比較、== は値を比較。None のチェックには is を使用

📝 練習問題

  1. 初級(難易度 ⭐):次の式の値を予測し、確認してください:

    • not (10 > 5)
    • True and False or True
    • not False and True
    • (5 > 3) or (2 > 10) and (8 == 8) —— ヒント:優先順位に注意——andor より優先順位が高い
  2. 中級(難易度 ⭐⭐):ユーザーの入力文字列を検証するコードを書いてください:

    • 入力が空の場合、「入力は空にできません」と出力
    • 入力がすべてスペースの場合も、「入力は空にできません」として扱う(ヒント:strip() を使用)
    • 入力の長さが 6 未満の場合、「入力は少なくとも 6 文字必要です」と出力
    • それ以外の場合、「入力は有効です」と出力
  3. 上級(難易度 ⭐⭐⭐):「3 桁の数値チェッカー」を書いてください。3 桁の数値 num(例:153)が与えられたとき、以下を判定します:

    • 偶数ですか?(% を使用)
    • 3 と 5 の両方で割り切れますか?
    • 回文数ですか?(百の位と一の位が等しい、例:121、353)
    • 上記の条件のうちいくつを満たしていますか?その数を出力してください。

    すべてのチェックにブール式のみを使用してください。if 文は使いません(次のレッスンで学びます)。

100%