順番に読み進めながら学べます

セイウチ演算子 := で代入と判定を 1 行に

Python 3.8 で追加されたセイウチ演算子 := を学びます。代入と判定を 1 行で書く基本と if / while パターンを図解で押さえます。

この記事で扱うセイウチ演算子 := は、代入と判定を 1 行で書くために Python 3.8 で導入された演算子です。:= の形がセイウチの牙に見えることからこの名前が付きました。ifwhile の条件式で記述量を減らせます。

セイウチ演算子の基本

= は、ifwhile などの式の中には書けませんでした。一方 :=なので、ifwhile条件式の中に直接書けます

変数 := 式 を用いれば、式の結果を変数に代入しながら条件式の値として使えます。

通常の代入とセイウチ演算子の違い
n = len(cart)if (n := len(cart))if n >= 3:>= 3 を評価本体を実行本体を実行True代入+取り出しTrue

左列の通常版は代入と判定を上から順に書きます。右列のセイウチ版1 つの条件式の中で代入と判定を同時に行います。

# 通常の書き方(2 行)
cart = ["リンゴ", "パン", "牛乳", "卵"]
n = len(cart)
if n >= 3:
    print(f"{n} 点で送料無料")

# セイウチ演算子版(1 行で代入 + 判定)
if (n := len(cart)) >= 3:
    print(f"{n} 点で送料無料")
# 出力: 4 点で送料無料

条件式の中で使うときは括弧で囲む

if n := len(cart) >= 3: のように括弧なしで書くと、len(cart) >= 3 が先に評価されて n に True/False が入ってしまいます。(n := len(cart)) >= 3 のように、代入したい式を括弧で囲むのが定石です。

if でセイウチ演算子を使う

if でよくあるのが、判定に使った値をそのまま本体の中でも使いたいというパターンです。通常は「代入してから判定」の 2 行に分けますが、セイウチ演算子なら値が必要な場所で一度だけ書けば済みます。

# 検索結果の件数で分岐し、本体でも件数を表示する
search_results = ["書籍A", "書籍B", "書籍C", "書籍D", "書籍E"]

if (hit_count := len(search_results)) >= 3:
    print(f"{hit_count} 件ヒットしました")
else:
    print("ヒットが少なすぎます")
# 出力: 5 件ヒットしました

ショッピングカートの金額判定をセイウチ演算子で書きます。

cart_prices = [1200, 800, 3500, 600](各商品の価格)を定義してください。

if の条件式の中で total := sum(cart_prices) と書き、total >= 5000 のときに「{total} 円:送料無料」と、そうでないときに「{total} 円:あと {5000 - total} 円で無料」と表示してください。

print(total)if の外側で呼び出し、同じ total が外からも参照できることを確認してください。

(正しく実行できれば解説が表示されます)

Python エディタ

コードを実行してください

while でセイウチ演算子を使う

while では、「取り出した値を条件にしながら、内部で利用したい」場合に使います。

while queue and (task := queue.pop(0))
while ループ開始queue は空?task := queue.pop(0)ループ終了(処理完了)本体で task を処理次のループへ戻る空でない空 (False)取り出し成功

ループのたびに まず queue が空かを確認します。空なら短絡評価で pop() は呼ばれず、そのままループを終了します。空でなければ queue.pop(0) で先頭を取り出して task に代入し、本体で task を使って処理を行い、次のループに戻ります。

# 待ち行列を先頭から 1 件ずつ消化する
pending_jobs = ["メール送信", "バックアップ", "デプロイ"]

while pending_jobs and (job := pending_jobs.pop(0)):
    print(f"処理中: {job}")
# 処理中: メール送信 / 処理中: バックアップ / 処理中: デプロイ

# pending_jobs が空になった瞬間に左側が False となり、pop() は呼ばれずにループを抜ける

pending_jobs and (job := pending_jobs.pop(0)) は、左側の pending_jobs が空(False)になった瞬間に短絡評価でループを抜けます。そのため、空リストに pop() を実行して IndexError が発生するバグを避けられます。

検索候補リストを上から順に 1 件ずつ表示します。

candidates = ["Tanaka Taro", "Suzuki Jiro", "Sato Hanako"] を定義してください。

while candidates and (name := candidates.pop(0)): で先頭から 1 件ずつ取り出し、「候補: {name}」と表示してください。

③ ループを抜けたら「全候補を確認しました」と表示してください。

Python エディタ

コードを実行してください

使いどころとトレードオフ

セイウチ演算子は書き方が短くなる以外に特別な機能はありません。1 行で書けるのは便利ですが、読みづらさの原因になることもあるので、使うべき場面を絞りましょう。

場面おすすめ理由
判定に使った値を、本体でそのまま再利用する使う2 行に分けると変数名が離れて読みにくい
while で取り出した値を条件にも本体にも使う使うループの終端条件と取り出しをまとめられる
条件の中で複雑な計算・副作用のある処理をする避ける式の中に処理が埋もれて追いづらくなる
単に代入したいだけで、条件式では使わない使わない普通の `=` の方が素直で読みやすい

この記事では、セイウチ演算子 := で代入と判定を 1 つの式にまとめる書き方を学びました。

QUIZ

理解度チェック

まずは1問ずつ答えてみましょう。

Q1次のコードの実行結果はどれですか?
items = [10, 20, 30]
if (n := len(items)) >= 2:
print(n)

Q2セイウチ演算子を if の条件式の中で使うときの書き方として正しいものはどれですか?

Q3セイウチ演算子 := の説明として最も適切なものはどれですか?