1.

Python if文完全ガイド(elif/三項/walrus/match/Truthy/ネスト回避)

編集
この記事の要点
  • Python の if 文: if cond: / elif cond: / else: でインデントで構造を表現
  • 三項演算子: x if cond else y(C 系の cond ? x : y 相当)
  • Walrus 演算子 := (3.8+) で式の中で変数代入: if (n := len(s)) > 10:
  • Truthy / Falsy: None / 0 / 空文字 / [] / {} は False 扱い
  • match 文 (3.10+) で構造的パターンマッチ。enum / dataclass で威力
  • 深いネストは 早期 return / ガード節で平坦化
  • 比較演算子は連結可能: 0 < x < 10(C 言語と異なる)

if 文の基本

age = 20

if age >= 20:
    print("成人")
elif age >= 18:
    print("18-19歳")
else:
    print("未成年")

# 1 行で書く(推奨されないが可能)
if age >= 20: print("成人")

C 系言語と異なり波括弧の代わりにインデントでブロックを表します。同じブロック内のインデントは揃える(4 スペース推奨、PEP 8)。

三項演算子

# x = (cond) ? a : b  (C 系)  →  Python では
x = a if cond else b

# 例
status = "成人" if age >= 20 else "未成年"

# ネストも可能(読みにくいので非推奨)
grade = "A" if score >= 90 else "B" if score >= 80 else "C"

# リスト内包と組み合わせ
nums = [n if n > 0 else 0 for n in data]  # 負数を 0 に

Truthy / Falsy

条件に直接渡せる値は多数。偽として扱われるものを覚えておくと簡潔に書けます。

Falsy(偽扱い)Truthy(真扱い)
False / NoneTrue
0 / 0.0 / 0j非ゼロの数値
""非空文字列("0" も True)
[] / () / {} / set()非空コレクション
カスタムクラスの __bool__ が False / __len__ が 0その他
# Pythonic な書き方
if items:                  # 空リストでなければ
    process(items)

if name:                   # 空文字でなければ
    print(name)

if value is None:          # None 専用判定(== None は非推奨)
    raise ValueError()

# ❌ 罠: 0 や '' を「未入力」扱いするバグ
def save(score):
    if not score:          # score=0 でもスキップされてしまう
        return
    db.save(score)

# ✅ 修正
def save(score):
    if score is None:
        return
    db.save(score)

Walrus 演算子 (:=)

Python 3.8+ で導入された代入式。条件式の中で変数を作れます。

# ❌ 従来: 2 行 + 重複計算
n = len(items)
if n > 10:
    print(f"too many: {n}")

# ✅ Walrus
if (n := len(items)) > 10:
    print(f"too many: {n}")

# ファイル読み込みループに便利
while chunk := f.read(8192):
    process(chunk)

# リスト内包内で
filtered = [y for x in data if (y := transform(x)) is not None]

# 入力検証
while not (name := input("name? ").strip()):
    print("空文字は不可")

match 文(3.10+ パターンマッチング)

# 単純な値マッチ
def http_status(code):
    match code:
        case 200 | 201 | 204:
            return "Success"
        case 301 | 302:
            return "Redirect"
        case 400:
            return "Bad Request"
        case 404:
            return "Not Found"
        case _:                    # _ は任意
            return "Unknown"

# 構造マッチ(タプル/リスト/dict/dataclass を分解)
def handle(event):
    match event:
        case {"type": "click", "x": x, "y": y}:
            print(f"clicked at {x},{y}")
        case {"type": "key", "value": v}:
            print(f"key: {v}")
        case [first, *rest]:
            print(f"list start={first}")
        case Point(x=0, y=0):       # dataclass
            print("origin")
        case _:
            print("unknown")

# ガード条件
match age:
    case n if n < 0:
        print("invalid")
    case n if n < 18:
        print("minor")
    case _:
        print("adult")

ネスト回避: 早期 return / ガード節

# ❌ 深いネスト
def process(user):
    if user is not None:
        if user.is_active:
            if user.has_permission:
                # ... 本処理 ...
                return True
            else:
                return False
        else:
            return False
    else:
        return False

# ✅ 早期 return で平坦化
def process(user):
    if user is None:
        return False
    if not user.is_active:
        return False
    if not user.has_permission:
        return False
    # ... 本処理 ...
    return True

比較演算子の連結

Python では 0 < x < 10 が数学通りに動きます。C 系言語と異なるので注意。

# Python では数学通り
if 0 <= score <= 100:
    print("valid")
# ↑ (0 <= score) and (score <= 100) と等価

# 3 つ以上もOK
if a < b < c < d:
    ...

# C 言語との違い
# C:  if (0 < x < 10)  → (0 < x) を bool 化(0 or 1) して < 10 → ほぼ常に真
# Python: 期待通り 0 < x and x < 10

FAQ

Q: x == Nonex is None どっち?
A: 必ず is None。None はシングルトン、__eq__ がオーバーライドされている可能性もあるため。

Q: switch 文はある?
A: 3.10+ の match 文が事実上の switch + パターンマッチ。それ以前は dict ディスパッチ {key: handler}[key]() や if-elif で代用。

Q: 三項演算子は使うべき?
A: 短く意味が明確なら積極的に。複数ネストは避けて通常の if-else に。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. if文
  2. switch

最近更新/作成されたページ