スライスで部分リストを取り出す
このレッスンで分かること
list[start:stop:step]の 1 行で部分リストを取り出せますstopは含まれません (半開区間[start, stop))- 最小例は
numbers[:3]で先頭 3 件、numbers[::-1]で反転
スライスで部分リストを取り出す とは
Python のスライス記法でリストの部分を切り出す方法を学びます。本レッスンでは、スライスで部分リストを取り出す の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
スライスで部分リストを取り出す
リストから「先頭 3 件だけ」「後ろから 2 件」「2 つおき」など、部分 を取り出したい場面は多いはず。Python はこれを スライス という記法でまとめて解決してくれます。for ループや if で 1 件ずつ取り出さなくても、たった一行で必要な範囲を切り抜ける、それがスライスの強みです。データ分析や前処理、Web API のレスポンス整形など、シーケンスを扱うあらゆる場面で スライス は活躍します。
スライスは
list[start:stop:step]の形で書きます。startを省略すれば先頭から、stopを省略すれば末尾まで、stepを省略すれば 1 つずつ進みます。
スライスとは何か
スライスは リスト タプル 文字列 などのシーケンス型に共通する記法です。[] の中に start stop step を コロン で区切って渡すだけで、対応する範囲を新しいリストとして返してくれます。元のリストを破壊しないので、安心して何度でも切り出せます。これは関数型プログラミングでよく言う「イミュータブル な操作」と相性が良く、副作用を最小化したコードを書きやすくしてくれます。
Python
numbers = [10, 20, 30, 40, 50]
print(numbers[1:4]) # [20, 30, 40]
print(numbers[:3]) # [10, 20, 30]
print(numbers[2:]) # [30, 40, 50]
print(numbers[::2]) # [10, 30, 50]
print(numbers[::-1]) # [50, 40, 30, 20, 10]注目すべきは stop の挙動です。numbers[1:4] は index 1 から 3 までで、4 は 含まれません。「stop は含まない」、これが Python のスライスの基本ルールです。range(1, 4) が 1, 2, 3 を生成するのと同じく、Python の世界では半開区間 [start, stop) がデフォルトになっています。
文法のおさらい
step を負の値にすると逆方向に走査でき、結果としてリストを反転させることもできます。下の表は numbers = [10, 20, 30, 40, 50] での代表的な例です。
| 書き方 | 結果 | 意味 |
|---|---|---|
numbers[0:2] | [10, 20] | 先頭から 2 件 |
numbers[-2:] | [40, 50] | 末尾 2 件 |
numbers[::-1] | [50, 40, 30, 20, 10] | 反転 |
numbers[1::2] | [20, 40] | 奇数 index だけ |
numbers[:-1] | [10, 20, 30, 40] | 末尾 1 件を除く |
負の index
-1は末尾の要素を指します。numbers[-2:]で「末尾 2 件」が取れるのは、start=-2stop=省略と書いているからです。
動きを追ってみる
図の流れを順序リストで書き直すと、次の通りです。
- 元のリストを参照する
start位置を決める (省略時は 0)stop位置を決める (省略時は末尾)step幅で要素を集める (省略時は 1)- 新しいリストとして返す (元のリストは変更されない)
スライスは「元のリストを変更せず、新しいリストを返す」という性質を覚えておきましょう。numbers[:3] の戻り値を変数に代入すれば、元の numbers は無傷のまま部分リストだけが新しく作られます。これを シャローコピー と呼びます。numbers[:] と書けばリスト全体の浅いコピーが手に入るので、コピー目的でもスライスは便利です。
Python
first_three = numbers[:3]
first_three.append(999)
print(first_three) # [10, 20, 30, 999]
print(numbers) # [10, 20, 30, 40, 50] ← 元データは変わらないスライスは文字列にも使えます。text = "PYTHON" のとき text[1:4] は "YTH"、text[::-1] は "NOHTYP" です。リストと文字列で同じ感覚が通じる、これも Python の気持ちよさの一つです。
よくある間違い
stopを「含まれる」と勘違いしてしまう。numbers[0:3]は index3を含まないので 3 件だけ取れる、と覚えましょう- 負の
stepのときstartとstopの指定順序を逆にしてしまう。numbers[4:0:-1]のように 大きい index から小さい index へ 書くのが正解です - スライスで返るのは元と同じ型の新しいシーケンス。
listをスライスすればlist、tupleをスライスすればtupleです。型が変わらないことに注意しましょう
スライスの範囲が空 (例えば
numbers[5:2]のようにstart >= stop) の場合は、エラーにならず空のリスト[]が返ります。IndexErrorを心配せず気軽に書ける、これがスライスの懐の深さです。
ここまでの要点
[start:stop:step]、stop は含まない、省略すると「先頭から」「末尾まで」「1 つずつ」。元のリストは破壊されず新しいリストが返る。
やってみよう
引数 lst (リスト) を受け取り、先頭 3 件 を返す関数 slice_head_three を書いてみましょう。要素数が 3 未満なら、入っているだけ返せば OK です。スライスの stop の挙動を実感する練習にぴったりの一問です。一行で書けることに気付けば、スライスの便利さが体に染み込みます。
よくある質問
Q. スライスの終端はなぜ含まれないのですか?
A. 終端 end が「次の位置」を指す半開区間にすることで、a[:k] + a[k:] が元の配列に等しくなり、長さも end - start で計算できる利点があります。len(a[2:5]) は常に 3 で、off-by-one を起こしにくい設計になっています。
Q. 負のインデックスはどう動きますか?
A. 末尾からの位置を表します。a[-1] は最後の要素、a[-3:] は末尾 3 件、a[:-1] は最後を除く全要素です。逆順にしたいときは a[::-1] と書けば手軽に反転でき、文字列でも同じく動きます('abc'[::-1] → 'cba')。
Q. スライスはコピーですか参照ですか?
A. Python のリストスライスは浅いコピーを返します。a[:] と書けばリスト全体のコピーになります。ネストしたリストの場合、内側のリストは元と同じ参照を保持するため、深いコピーが必要なら copy.deepcopy を使ってください。
次のレッスン
次は リスト内包表記でループを 1 行に で、Python のスライス記法でリストの部分を切り出す方法を学びます を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- スライス の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. スライス とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
要件
- スライス記法
lst[:3]を使って先頭 3 件を返す - 元のリストを破壊しない
- 要素数が 3 未満でもエラーにならない
入出力例
test-cases.txt
slice_head_three([10,20,30,40,50]) → [10,20,30]
slice_head_three(["a","b","c"]) → ["a","b","c"]
slice_head_three([1,2]) → [1,2]
slice_head_three([]) → []