Python | 文法の基本:代入演算子

Python
スポンサーリンク

代入演算子の概要(= と「値に名前をつける」)

Pythonの代入演算子は「=」です。右辺の式を評価し、その結果オブジェクトへ左辺の名前を結びつけます。数学の「等しい」ではなく「割り当てる」の意味です。代入は値そのものを書き換えるのではなく「名前がどのオブジェクトを指すか」を切り替えます。

x = 10          # x は 10 を指す
x = x + 5       # 右辺を評価(15)→ x が 15 を指すように更新
name = "Python" # 文字列も同様
Python

基本代入と複合代入(+= など)の違い

基本代入(=)

「右辺の結果」を左辺の名前に結びつけるだけです。オブジェクトの種類が異なっても構いません。

a = 1
a = "one"   # 問題なし(動的型付け)
Python

複合代入(+=, -=, *=, /=, //=, %=, **=)

「計算して同じ変数に再代入」を短く書く記法です。数値の累計、文字列やリストの結合などで読みやすさと意図の明確化に役立ちます。

total = 0
total += 120
total += 340
# total は 460

text = "Py"
text += "thon"
# "Python"
Python

複合代入は「同じ変数を更新する」意図が明確で、ループの集計やバッファの構築に最適です。


インプレース更新の深掘り(iadd とミュータブルの挙動)

ミュータブル(リスト・辞書など)は「中身を更新」しやすい

複合代入は、対象型がミュータブル(変更可能)なら「その場更新(in-place)」を試みます。成功すると同じオブジェクトのまま中身が変わります。リストの += は extend と同じ挙動です。

nums = [1, 2]
alias = nums
nums += [3]          # in-place(extend)
print(nums, alias)   # [1, 2, 3] [1, 2, 3](同じものが更新される)
Python

イミュータブル(int・str・tuple)は「新しいオブジェクトへ」

イミュータブル型では in-place ができないため、複合代入でも新しいオブジェクトが作られます。参照を共有していても、片方の更新はもう片方に影響しません。

s = "Py"
t = s
s += "thon"         # 新しい文字列が作られ s が差し替わる
print(s, t)         # "Python" "Py"(t は変わらない)

x = 10
y = x
x += 5              # 新しい int を指すように
print(x, y)         # 15 10
Python

この違いは「副作用の有無」に直結します。共有参照を持つ変数に対して複合代入を使うときは、対象がミュータブルかどうかで結果が変わる点に注意してください。


複数代入とアンパック、連鎖代入のコツ

同時代入(タプルアンパック)

右辺の並びを左辺に展開して代入します。一時変数なしの入れ替えや、返り値の分配で可読性が上がります。

a, b = 10, 20
a, b = b, a         # スワップ
x, y, z = (1, 2, 3) # タプルから展開
Python

可変長は「*」で受けられます。

head, *rest = [10, 20, 30, 40]  # head=10, rest=[20, 30, 40]
Python

連鎖代入(同じ値を複数へ)

同じ右辺を複数名へまとめて代入します。ミュータブルを共有したくない場合は避けるかコピーを使って安全確保します。

a = b = 0          # どちらも 0 を指す(問題なし)

lst1 = lst2 = []   # 同じリストを共有(危険)
lst1.append(1)
print(lst2)        # [1] に連動してしまう
# 対策
lst1, lst2 = [], []            # 別オブジェクトにする
# または
import copy
lst1 = []
lst2 = copy.copy(lst1)
Python

代入式(ウォルラス演算子 :=)の使いどころ

値を生成しつつ、その場で名前に保持

「評価した結果を変数へ代入し、その値を式中で使う」構文です。入力検証やループでの一時結果の再利用に向いています。読みやすさを保つ範囲で使い、過度なワンライナー化は避けます。

# 条件の中で計算結果を保持
if (n := len("Python")) > 5:
    print(n)  # 6

# ループでの読み取りと判定を一度に
while (line := input().strip()):
    print(line)
# 空行で終了
Python

よくある落とし穴と安全な代入のパターン

共有参照の意図せぬ連動

ミュータブルを別名で使うと、片方の更新がもう片方に影響します。独立性が必要なときはコピー(浅い・深いの選択)を明示します。

import copy
data = [[1], [2]]
shallow = data[:]            # 浅いコピー
deep = copy.deepcopy(data)   # 深いコピー
Python

型が変わる複合代入

/= は int を float に変えます。後続処理で型前提があるなら、意図をコメントや明示的な変換で伝えます。

count = 5
count /= 2    # 2.5(floatへ)
# 整数を保ちたいなら
count = count // 2  # 2(切り捨て)
Python

代入と比較の取り違え

Pythonでは「== が比較、= が代入」です。条件式で代入をする言語と違い、if x = 1 は構文エラーになります。可読性のためにも混同を避けましょう。


例題で身につける

例題1:集計と複合代入で読みやすく

prices = [120, 340, 560]
total = 0
for p in prices:
    total += p
print(total)  # 1020
Python

例題2:文字列バッファの構築(+= と join の使い分け)

少量なら += で十分。大量結合は join が高速でメモリ効率も良いです。

lines = ["A", "B", "C"]
buf = ""
for s in lines:
    buf += s + "\n"          # 小規模なら可
# 大量なら
buf2 = "\n".join(lines) + "\n"
Python

例題3:ウォルラスで一時結果を保持しつつ判定

def read_non_empty():
    while (line := input(">> ").strip()):
        print(f"read: {line}")
    print("done")
Python

例題4:連鎖代入の安全な使い方

# カウンタの初期化(イミュータブルなら安全)
i = j = k = 0

# ミュータブルは別々に
a, b = [], []
Python

まとめ

代入は「名前とオブジェクトの結びつき」を切り替える操作です。複合代入は更新意図を短く明快にし、ミュータブルなら in-place、イミュータブルなら新オブジェクトへ置き換わります。複数代入・アンパックは可読性を高め、連鎖代入はミュータブル共有に注意。ウォルラスは「計算結果を保持しつつ使う」場面で効果的です。これらの挙動と落とし穴を押さえるだけで、代入周りのバグや誤解は大幅に減らせます。

タイトルとURLをコピーしました