【未経験から始めるPython基礎④】リストの結合、「+」「+=」の違いとスライス

6 min 65 views
未経験から始めるPython④

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]
(参照だから)

  1. a = [1, 2, 3, 4]
    • ある場所にリスト [1, 2, 3, 4] が作られます。
  2. b = a
    • b に「a と同じリストの場所」を教えているだけ。
    • 新しいリストをコピーしているわけではありません。
  3. b.append(5)
    • b が指しているリストに 5 を追加 →
    • a も同じリストを指しているので、中身は [1, 2, 3, 4, 5] に変わる。
  4. 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 は別物なので変わりません

関連記事