Python を学び始めると、まず最初につまずきやすいのが “リスト操作” です。
特に、次のようなコードを見たときに
prime_numbers = [2, 3, 5, 7, 11]
prime_numbers + [13, 17, 19]
prime_numbers += [13, 17, 19]
prime_numbers[5:] = []
print(prime_numbers)
「結局どう動いているの?」と混乱することが多いはずです。
この記事では、上記のコードを軸に リストの結合・代入・削除・スライス まで一気に理解できます。
Python 初学者が “ここで一気に理解しておくと、この先がラクになる” という内容を詰め込みました。
目次
◆ はじめに|最終的な出力はこうなる
上のコードを実行すると、最終的にこう表示されます。
[2, 3, 5, 7, 11]
そして実は、次の短いコードでも同じ結果になります。
prime_numbers = [2, 3, 5, 7, 11]
prime_numbers += [13, 17, 19]
prime_numbers[5:] = []
print(prime_numbers)
なぜ同じになるのか?
それを理解しながら、リスト操作の本質を学んでいきましょう。
◆ 「+」と「+=」の決定的な違い
1. a + b は “新しいリストを作るだけ”
prime_numbers + [13, 17, 19]
この行は新しいリストを作りますが、どこにも代入していないためリスト自体は変わりません。
図にするとこうです
prime_numbers --------> [2, 3, 5, 7, 11]
prime_numbers + [...] -> [2, 3, 5, 7, 11, 13, 17, 19](作っただけで捨てている)
2. a += b は “元のリストを直接書き換える”
prime_numbers += [13, 17, 19]
これは 破壊的変更(in-place) と呼ばれる操作で、
もとのリストに直接要素が追加されます。
[2, 3, 5, 7, 11]
↓
[2, 3, 5, 7, 11, 13, 17, 19]
◆ スライス代入で削除ができる|a[i:] = []
今回のコードのポイントはこの1行です。
prime_numbers[5:] = []
これは「インデックス5番目(6個目)から最後まで」を空リストに置き換える=削除する、という意味。
削除される部分はこう
[13, 17, 19]
結果、リストは元の5要素だけになります。
◆ ここから本題:Python のスライスを深掘りしよう
スライスは、Python を扱う上で絶対に避けて通れない超重要構文です。
基本形はこう
リスト[start:end]
意味は start 以上 end 未満。
※「先頭から end−1 番目まで」を意味します。
◆ スライスの使い方まとめ
基本:start〜end-1 を取り出す
nums[1:4] # 1〜3番目
省略パターン
| 書き方 | 意味 |
|---|---|
a[:end] | 先頭〜end-1 |
a[start:] | start〜最後まで |
a[:] | 全体のコピー |
3つ目の値 step を使う
nums[::2] # 2個とばし
逆順にする裏ワザ
nums[::-1]
スライス代入でできる3つのこと
① 部分置換
nums[1:3] = [20, 30]
② 部分削除
nums[2:5] = []
# または del nums[2:5]
③ 挿入(start=end のとき)
nums[2:2] = [100, 200] # ここに挿入される
◆ 図で理解するスライス(直観イメージ)
nums = [10, 20, 30, 40, 50, 60]
インデックス: 0 1 2 3 4 5
nums[2:5] → [30, 40, 50] # 2〜4
nums[:3] → [10, 20, 30] # 先頭〜2
nums[3:] → [40, 50, 60] # 3〜最後
nums[::2] → [10, 30, 50] # 飛ばし
nums[::-1] → [60, 50, 40, 30, 20, 10] # 逆順
◆ スライスはコピーにも使える
copy_nums = nums[:]
これはシャローコピー(浅いコピー)。
リストを複製したいときによく使うテクニックです。
◆ この記事の総まとめ
リスト操作の基礎を押さえるポイントは以下の3つだけ。
✔ 1. + と += の違い
| 記法 | 動き | リストは変わる? |
|---|---|---|
a + b | 新しいリストを作る | ❌ 変わらない |
a += b | 元のリストに追加 | ✅ 変わる |
✔ 2. スライスは「start〜end-1」
a[i:j]は i〜j-1- 省略形、逆順、step の組み合わせで何でもできる
✔ 3. スライス代入で「削除/置換/挿入」ができる
a[i:j] = []→ 削除a[i:j] = [X]→ 置換a[i:i] = [X]→ 挿入
◆ Python の理解が一段階進むポイント
スライスの理解は、Python でのデータ加工・変換・整形を行う上で必須の基礎になります。
- テキスト処理
- データ分析
- Webスクレイピング
- ゲーム開発
- AIや機械学習の前処理
どのジャンルでもスライスを毎日のように使います。
一度 “感覚で理解できるレベル” まで落とし込めると、Python のコードが一気に扱いやすくなるはずです。
◆ 補足①|“ミュータブル”と“イミュータブル”を知ると理解が深まる
Python のデータ型には大きく ミュータブル(mutable)=変更できる と
イミュータブル(immutable)=変更できない の2種類があります。
| 種類 | データ型 | 特徴 |
|---|---|---|
| ミュータブル | list, dict, set | 中身の変更が可能 |
| イミュータブル | int, float, str, tuple | 中身を変更できない |
今回の += の挙動も、この違いが関係しています。
リストはミュータブル
a = [1, 2]
a += [3]
→ 元のリスト自体が書き変わる(破壊的処理)
文字列はイミュータブル
s = "abc"
s += "d"
→ 新しい文字列を作り直して s に再代入している
「なぜ同じ += でも動きが違うの?」と思ったとき、
この “mutable / immutable の違い” を知っておくと理解が一段上がります。
◆補足②|コピーと参照の違い(初心者が必ずつまずくポイント)
Python のリストは “参照” という仕組みで動いています。
a = [1, 2, 3]
b = a
b.append(4)
print(a) # [1, 2, 3, 4]
なぜ a まで変わるの?
b = aは「中身をコピーした」のではなく
a と b が同じリストを指しているだけ だからです。
リストをコピーしたいなら、スライスが役に立ちます。
b = a[:] # ← シャローコピー
これで「a と b は別物(独立したリスト)」になります。
スライスは“部分取得”だけでなく、“コピー”として使える、便利な技です。
◆補足③|スライスが強い理由:Python の“範囲指定”は一貫している
Python のスライスは
start ≤ index < end
という「数学的な半開区間」で動いています。
これ、実は Python のほぼすべての範囲指定の動きと同じです。
例:
range(2, 5) # 2, 3, 4
文字列[1:4] # インデックス1〜3
リスト[1:4] # インデックス1〜3
この “end が含まれない” というルールを知っておくと、Python の挙動に無駄な混乱がなくなります。
◆補足④|破壊的変更と非破壊的変更を見分ける癖をつけよう
Python を書くときに非常に重要なのが
「この操作は元のデータを書き換えるのか? 新しく作るのか?」
を意識することです。
今回なら
| 書き方 | 種類 | 元のリストは変わる? |
|---|---|---|
a + b | 非破壊的 | ❌ |
a += b | 破壊的 | ✅ |
a[i:j] = [] | 破壊的 | ✅ |
del a[i:j] | 破壊的 | ✅ |
a[:] | 非破壊的(コピー作成) | ❌ |
破壊的処理は強力な反面、「気づかないうちにデータが変わっていた!」という事故につながることがあります。
Python を扱ううえで、ここを意識するだけでコードの安定性はグッと上がります。
◆補足⑤|スライス操作の練習問題(答えつき)
Q1.
a = [10, 20, 30, 40, 50]
print(a[1:4])
答え → [20, 30, 40]
Q2.
a = [1, 2, 3, 4, 5]
a[2:] = []
print(a)
答え → [1, 2]
Q3.
a = [1, 2, 3, 4, 5]
a[1:3] = [9, 9, 9]
print(a)
答え → [1, 9, 9, 9, 4, 5]
a[1:3] = [9, 9, 9] は、「インデックス1〜2の部分(2と3)を 9, 9, 9 に置き換える」 って意味です。
Q4.
a = [1, 2, 3, 4]
b = a
b.append(5)
print(a)
答え → [1, 2, 3, 4, 5]
(参照だから)
a = [1, 2, 3, 4]- ある場所にリスト
[1, 2, 3, 4]が作られます。
- ある場所にリスト
b = a- b に「a と同じリストの場所」を教えているだけ。
- 新しいリストをコピーしているわけではありません。
b.append(5)- b が指しているリストに
5を追加 → - a も同じリストを指しているので、中身は
[1, 2, 3, 4, 5]に変わる。
- b が指しているリストに
print(a)- その結果、
[1, 2, 3, 4, 5]と表示される。
- その結果、
つまり a と b は 別々の箱ではなく、同じ箱を共有しているイメージです。
「参照」をざっくり定義すると
変数が値そのものを持っているのではなく、「その値が置いてある場所(アドレス)」だけを持っている状態。
リストや辞書などの ミュータブル(中身を変えられる)なオブジェクト は、この「参照」で扱われます。
Q5.
a = [1, 2, 3]
b = a[:]
b.append(4)
print(a)
答え → [1, 2, 3]
(コピーしたので a は変わらない)
a[:] は リストを丸ごとコピーする書き方です。
だから b に4を足しても、元の a は別物なので変わりません。





