1.はじめに
Pythonでプログラミングをしていると、append() や replace()、sort() など、よく使うメソッドがたくさん登場しますよね。でも、同じように見える操作なのに、「あるときは変数の中身が書き換わっていて、別のときは元のまま…」なんてこと、経験ありませんか?
実はこれ、「破壊的な処理」か「非破壊的な処理」かの違いなんです。
- 「破壊的」とは、元のデータ(変数の中身)を書き換える処理のこと。
- 「非破壊的」とは、元のデータはそのままで、新しいデータを返す処理のこと。
この違いをちゃんと意識していないと、
「あれ?文字列を置き換えたのに変わってない…」
「リストを並べ替えたのに戻り値がNone?」
なんて混乱しがちです。
この記事では、破壊的・非破壊的な処理の違いをPythonの具体例でわかりやすく解説します。どういうときにどちらを選ぶべきか、メリット・デメリットも含めてやさしく説明していきます。
初心者のうちからこの違いを理解しておくと、バグの少ない安全なコードが書けるようになりますよ!
2.破壊的メソッドと非破壊的メソッドとは?
Pythonでは、同じように見える操作でも「元のデータが書き換わるかどうか」によって、破壊的か非破壊的かが分かれます。この違いをしっかり理解しておくと、予期せぬバグを防ぐことができ、コードも読みやすくなります。
破壊的メソッドとは?
破壊的メソッドは、元のオブジェクト(変数の中身)を直接変更するタイプの処理です。つまり、処理のあとに同じ変数を使うと、中身がすでに書き換わっています。
例:リストの append() メソッド
x = [1, 2, 3]
x.append(4)
print(x) # [1, 2, 3, 4]
この例では、x.append(4) を実行した時点で、x の中身が書き換わっています。戻り値は None なので、間違えて y = x.append(4) としてしまうと、y には何も入らず None になります。
非破壊的メソッドとは?
一方、非破壊的メソッドは、元のオブジェクトをそのままにして、新しいデータを返すタイプの処理です。元の変数はそのままで、戻ってきた値を使って新しい変数に保存する必要があります。
例:文字列の replace() メソッド
name = "田中さん"
new_name = name.replace("さん", "様")
print(name) # 田中さん(元のまま)
print(new_name) # 田中様(新しい文字列)
このように、replace() は 非破壊的なので、name の中身は変わりません。変更結果を使いたいときは、戻り値を別の変数(ここでは new_name)に代入する必要があります。
メソッドごとの性質を意識しよう
Pythonにはこのように、破壊的なメソッドと非破壊的なメソッドが混在しています。どちらの処理かを意識せずに使ってしまうと、以下のような混乱が起こりがちです。
- 破壊的なのに戻り値を使おうとして
Noneになる - 非破壊的なのに、元の変数が変わったと思い込んでしまう

次は、こうしたメソッドの実例をもっと見ていきましょう!
3.実例で学ぶ|Pythonでよく使う破壊的・非破壊的な処理
ここでは、Pythonでよく使われる代表的なメソッドや操作を「破壊的」「非破壊的」に分けて、実際のコード例と一緒に紹介します。動きを見て、自分で書くときの参考にしてみてください。
🔸 リストの追加:append()(破壊的)
fruits = ["りんご", "バナナ"]
fruits.append("みかん")
print(fruits) # ['りんご', 'バナナ', 'みかん']
この append() は破壊的です。リスト fruits 自体が変更されているため、戻り値は None になります。
🔸 リストの結合:+(非破壊的)
a = [1, 2, 3]
b = a + [4, 5]
print(a) # [1, 2, 3](元のまま)
print(b) # [1, 2, 3, 4, 5]
+ を使ったリストの結合は非破壊的です。元のリスト a は変わらず、新しいリスト b が作られます。
🔸 並び替え(ソート):sort() vs sorted()
sort()(破壊的)
numbers = [5, 3, 1, 4, 2]
numbers.sort()
print(numbers) # [1, 2, 3, 4, 5]
sort() はリストを直接並べ替える破壊的な処理です。元のリストが変更されます。
sorted()(非破壊的)
nums = [5, 3, 1, 4, 2]
sorted_nums = sorted(nums)
print(nums) # [5, 3, 1, 4, 2](元のまま)
print(sorted_nums) # [1, 2, 3, 4, 5]
sorted() は元のリストはそのままで、新しい並び順のリストを返す非破壊的な関数です。
🔸 文字列の置き換え:replace()(非破壊的)
greeting = "こんにちは、田中さん"
new_greeting = greeting.replace("田中さん", "山田様")
print(greeting) # こんにちは、田中さん
print(new_greeting) # こんにちは、山田様
文字列の replace() は非破壊的なメソッドです。元の文字列はそのまま、新しい文字列が返されます。
🔸 辞書の更新:update()(破壊的)
info = {"name": "佐藤", "age": 25}
info.update({"age": 26})
print(info) # {'name': '佐藤', 'age': 26}
update() は元の辞書の中身を直接変更する破壊的メソッドです。
🔸 リストの削除:remove()(破壊的)
nums = [1, 2, 3, 4]
nums.remove(2)
print(nums) # [1, 3, 4]
remove() は要素を削除する破壊的処理です。元のリストが変更されます。

こうした例を見てわかるように、**「元のデータが変わるか変わらないか」**をしっかり意識することが大切です。間違って return を使おうとして「Noneになった…」というトラブルを防ぐためにも、今のうちに整理して覚えておきましょう。
4.pandasのinplace=Trueはどういう意味?
Pythonでデータ分析をしていると、よく使われるライブラリ「pandas(パンダス)」。その中には、多くのメソッドで登場する「inplace=True」という引数があります。
この inplace は、ここまで紹介してきた**「破壊的か非破壊的かを選べるスイッチ」**のようなものです。
🔹 inplace=False(デフォルト)=非破壊的
まず、inplace=False(または何も指定しない)の場合は、非破壊的です。元のDataFrameはそのままで、新しいデータを戻り値として返します。
import pandas as pd
df = pd.DataFrame({"name": ["佐藤", "佐藤", "田中"]})
new_df = df.drop_duplicates()
print(df) # 元のデータはそのまま
print(new_df) # 重複が削除された新しいデータ
🔹 inplace=True=破壊的
一方で、inplace=True を指定すると、破壊的な処理になります。戻り値は None になり、元のDataFrameが直接変更されます。
df = pd.DataFrame({"name": ["佐藤", "佐藤", "田中"]})
df.drop_duplicates(inplace=True)
print(df) # 元のdfが変更され、重複がなくなっている
🔹 どっちを使うべき?
| 比較ポイント | inplace=False(非破壊的) | inplace=True(破壊的) |
|---|---|---|
| 戻り値 | 新しいDataFrameを返す | None |
| 元のデータ | 変更されない | 変更される |
| 可読性 | 高い(変数で明示できる) | やや低い |
| メモリ効率 | 悪い(データコピー) | 良い |
基本的には、**「コードの安全性」と「可読性」**を重視するなら、inplace=False(非破壊的)をおすすめします。操作の結果を新しい変数に保存することで、元のデータを残しつつ処理ができるので安心です。

実は、pandasの開発チームは今後「inplaceを廃止する方向」に進んでいます(理由は可読性・一貫性・メンテナンス性の向上)。そのため、非破壊的なコードを書く習慣を早めに身につけておくと安心です。
5.非破壊的処理が推奨される理由
Pythonでは、「非破壊的な処理」が推奨される場面がとても多いです。というのも、非破壊的な処理はコードの安全性が高く、読みやすく、保守性も高いというメリットがあるからです。
ここでは、その理由をわかりやすく紹介していきます。
🔹 1. 予期しない副作用を防げる
破壊的な処理では、変数の中身が知らないうちに変わってしまうことがあります。
def add_item(my_list):
my_list.append("新しいアイテム")
items = ["りんご"]
add_item(items)
print(items) # ['りんご', '新しいアイテム'] ← 変更されてる!
このように、関数の中でリストを変更すると、外の変数まで書き換わってしまうことがあります。これは「副作用」と呼ばれるもので、バグの原因になりやすいです。
非破壊的に書けば、副作用を回避できます。
def add_item(my_list):
return my_list + ["新しいアイテム"]
items = ["りんご"]
new_items = add_item(items)
print(items) # ['りんご'](元のまま)
print(new_items) # ['りんご', '新しいアイテム']
🔹 2. 「変わった」ことがコードで明確になる
非破壊的処理では、代入(=)によって変化が見えるため、コードの流れが追いやすくなります。
# 非破壊的な場合
new_data = old_data.replace("田中", "山田")
このように「どこで何が変わったのか」がハッキリ見えるのがポイントです。読み手にとってもわかりやすく、保守・再利用にも向いています。
🔹 3. テストやデバッグがしやすくなる
非破壊的な処理は、元のデータを残したまま別の処理を試せるため、テストやデバッグがしやすくなります。
たとえば「どこまでの処理でデータがどう変化したのか」を段階的に確認したいとき、非破壊的なコードはとても役立ちます。
🔹 4. チーム開発や関数の再利用にも強い
誰かの書いた関数を安心して使えるかどうかは、その関数がデータを勝手に変えないかどうかにかかっていることも多いです。
非破壊的な処理なら、外部から渡されたデータを壊す心配がなく、関数としての再利用性が高くなります。

もちろん、すべての場面で非破壊的な処理がベストというわけではありませんが、迷ったら非破壊的に書くのが基本方針です。
6.破壊的処理を選ぶべき場面もある
これまで「非破壊的な処理」のメリットをたくさん紹介してきましたが、実は破壊的な処理が適している場面もあります。
「絶対に非破壊的にすべき!」というわけではなく、場面に応じて正しく選ぶことが大切です。
🔹 1. メモリやリソースを節約したいとき
非破壊的な処理は、新しいオブジェクトを作るという性質上、メモリを多く使うことになります。特に、扱うデータが大きい場合は注意が必要です。
例:リストのソート
# 非破壊的:新しいリストを作る(メモリ使用多)
sorted_list = sorted(my_list)
# 破壊的:元のリストを並べ替える(メモリ効率が良い)
my_list.sort()
大量のデータを扱うプログラムや、組み込み機器などリソースに限りがある環境では、破壊的な方法の方が適しているケースもあります。
🔹 2. すでに使い捨て前提の変数であるとき
一時的なデータや、「もうこの変数は今後使わない」とわかっている場合は、破壊的に処理した方がシンプルなこともあります。
temp = get_large_data()
temp.sort() # このあとtempはもう使わない
こういった場面では、わざわざ新しい変数を作る必要もなく、破壊的な方が効率的でコードも短くなります。
🔹 3. 処理スピードを重視したいとき
破壊的な処理は、データをその場で変更するため、高速な処理が可能です。とくにリアルタイム性が求められる処理では、破壊的なメソッドが選ばれることもあります。
ただし、これはミリ秒単位の話になることが多く、通常の学習や小規模なスクリプトでは大きな差が出ることは少ないです。
✅ 結論:目的に応じて使い分けよう
| 目的 | 推奨される処理方式 |
|---|---|
| 安全性・読みやすさが重要 | 非破壊的処理 |
| メモリ・スピードを重視したい | 破壊的処理 |
| 一時的な変数への処理 | 破壊的処理でもOK |

破壊的・非破壊的のどちらが正解ということではなく、目的に合わせて最適な方法を選ぶのがベストです。
まとめ|処理の種類を意識して、安全なコードを
この記事では、Pythonにおける**「破壊的」と「非破壊的」な処理の違い**について、実例とともに解説してきました。
もう一度、ポイントを整理しておきましょう。
✅ この記事のまとめ
- 破壊的な処理は、変数の中身そのものを変更します(例:
append(),sort())。 - 非破壊的な処理は、新しいオブジェクトを返すだけで、元のデータは変わりません(例:
replace(),sorted())。 - 非破壊的な処理の方が安全性が高く、バグを防ぎやすいため、基本はこちらを推奨。
- ただし、メモリ効率や処理スピードを重視する場合は破壊的処理も選択肢に入ります。
- pandasの
inplace=Trueのように、処理方法を選べるケースもあるので、ドキュメントを確認する習慣をつけましょう。
🧠 これからのコーディングで意識すべきこと
プログラムを書くときは、**「この操作は元のデータを変えるのか? それとも新しいものを返すのか?」**を常に意識しましょう。
これだけで、コードの安全性・読みやすさ・保守性がグッと上がります!
「なんでこの変数、変わってるの?」
「なんで戻り値がNoneになったの?」
そんなトラブルを減らすためにも、今日学んだ考え方をしっかり身につけていきましょう!
あわせて読みたい
Pythonをもっと安全に・スッキリと書くために、以下の記事もぜひあわせてご覧ください!
🔗 【Python入門5】リストの使い方と関数・メソッドの違いを初心者向けにやさしく解説!
リスト操作でよく使うメソッドの違いをまとめて解説!破壊的なものと非破壊的なものをしっかり見分けよう。
🔗 初心者でもすぐわかる!Pythonのクラス入門ガイド|オブジェクト指向をやさしく解説
オブジェクトの性質と振る舞いを学べば、破壊的・非破壊的処理ももっと深く理解できます!
🔗 【Python入門】引数のデフォルト値とタイプアノテーションの使い方をやさしく解説!
関数を定義するときに便利な機能を知れば、破壊的なミスも予防できる!
よくある質問(Q&A)
- Q
list.append()の戻り値を変数に入れたらNoneになりました。なぜ? - A
append()は破壊的なメソッドで、リスト自体を変更します。そのため、戻り値は常にNoneです。x = [1, 2]
y = x.append(3)
print(y) # → Noneこのように代入しても意味がないので、
x.append(3)のように直接呼び出して使いましょう。
- Q文字列の
replace()を使ったのに、元の文字列が変わりません… - A
replace()は非破壊的なメソッドです。元の文字列を変えるのではなく、新しい文字列を返すだけです。text = "こんにちは"
text.replace("にち", "ばん") # このままだとtextは変わらない結果を使いたい場合は、戻り値を新しい変数に代入しましょう。
new_text = text.replace("にち", "ばん")
- Q破壊的なメソッドを使ってもエラーにならないのに、非破壊的なものは代入しないと効果がないのはなぜ?
- A
破壊的な処理は「その場で変更」が行われるので、戻り値を受け取らなくても動きます。
一方、非破壊的な処理は「新しい値を作って返す」仕組みなので、戻り値を受け取らないと何も変わっていないように見えるのです。







※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。
※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。