文字列の一部を直接書き換えようとした原因と直し方
文字列の一部を直接書き換えようとしたときに出るエラーです。Pythonの文字列は不変(immutable)です。
エラーメッセージの読み方
Traceback (most recent call last):
main.py- ファイル名
2- 行番号 — 実際にクラッシュした行
<module>- 発生場所 — <module> ならトップレベル、関数名ならその関数の中
TypeError- 例外クラス — 何が起きたか。ここを検索するのが最短です
'str' object does not support item assignment- 詳細メッセージ — どの値が問題だったか
このエラーが出る典型パターン
パターン1
1 name = "tom" 2 name[0] = "T" ^ 3 print(name)
文字列は不変(immutable)なので、一部だけを書き換えることはできません。新しい文字列を作って変数に代入し直します。
直し方: name[0] = "T" を name = "T" + name[1:] にします。
パターン2
1 s = "hello" 2 s[-1] = "O" ^ 3 print(s)
末尾の文字を変えたい場合も同様です。スライスで前半部分を取り出し、新しい文字をつなげて再代入します。
直し方: s[-1] = "O" を s = s[:-1] + "O" にします。
パターン3
1 word = "cat" 2 word[1] = "u" ^ 3 print(word)
真ん中の文字を変える場合も、前後をスライスで切り出して新しい文字列に組み立て直します。
直し方: word[1] = "u" を word = word[0] + "u" + word[2:] にします。
パターン4
1 s = "abc" 2 s[1:] = "XY" ^ 3 print(s)
スライスを使って範囲を指定しても、文字列への代入である以上は同じエラーになります。
直し方: s[1:] = "XY" を s = s[0] + "XY" にします。
パターン5
1 text = "data" 2 del text[0] ^ 3 print(text)
1文字だけ削除するdel text[0]も、文字列の一部を変更しようとしている点では代入と同じ扱いです。
直し方: del text[0] を text = text[1:] にします。
よくある誤解
リストの要素のように書き換えられると思われがちですが、文字列は一度作られたら中身を変更できません。変更したい場合は新しい文字列を作って再代入します。
実務での勘所
文字列が不変である設計の理由の一つは、辞書のキーや集合の要素として安全に使うためです。ハッシュ値は一度計算したら変わらないことが前提になっており、キーにした後で中身が変わってしまうと辞書の内部構造が壊れます。文字列を1文字ずつ編集したい場合の定石は、list(s)でいったん文字のリストに変換して要素を書き換え、"".join(chars)で1つの文字列に戻す方法です。頻繁に文字列を組み立てる処理では、+=を繰り返すより効率的です。