閉じる

【Python】リストの一部を取り出す方法:スライスの書き方とコツ

リストの一部を抜き出す方法は、Pythonではスライスと呼ばれます。

スライスを使うと、範囲指定で安全かつ簡潔に部分列を取り出せるため、要素の抽出、並べ替え、コピーなど多くの場面で役立ちます。

本記事では、基本の記法、よく使う省略、実践テク、注意点を、丁寧なサンプルコードと出力つきで解説します。

Pythonのリストのスライスとは?

スライスの基本(部分取り出し)

スライスは、リストの一部を新しいリストとして取得する仕組みです。

元のリストを壊さずに、必要な範囲だけを抽出できます。

Python
# 基本となるリスト
nums = [10, 20, 30, 40, 50, 60]

# 2番目から4番目までを取り出す例(インデックスは0始まり)
part = nums[1:4]  # 20, 30, 40 が取り出される
print(part)
print(nums)  # 元のリストは変化しません
実行結果
[20, 30, 40]
[10, 20, 30, 40, 50, 60]

構文 list[start:end] の書き方

スライスの基本構文はlist[start:end]です。

start以上、end未満の要素が対象になります。

例えばa[2:5]は、インデックス2, 3, 4を取得します。

Python
a = ['a', 'b', 'c', 'd', 'e', 'f']
print(a[2:5])  # c, d, e を取得
実行結果
['c', 'd', 'e']

インデックスは0始まり

Pythonのインデックスは0から始まります

先頭は0、2番目は1です。

Python
letters = ['A', 'B', 'C', 'D']
print(letters[0], letters[1])  # 先頭と2番目を確認
print(letters[0:2])            # 0以上2未満 → A, B
実行結果
A B
['A', 'B']

endは含まない(半開区間)

右端のendは含まれません(半開区間)。

これにより、連続した範囲を重ねても重複が起きず、境界の計算が簡単になります。

Python
x = [0, 1, 2, 3, 4]
print(x[1:3])  # 1, 2 を取得。3は含まれない
print(x[:3])   # 0, 1, 2
print(x[3:])   # 3, 4
実行結果
[1, 2]
[0, 1, 2]
[3, 4]

範囲外アクセス時の挙動(例外にならない)

スライスは、範囲外でも例外にならず、存在する範囲だけを返します。

一方、添字アクセスa[index]は範囲外でIndexErrorになります。

Python
a = [1, 2, 3]

# スライスは静かに空リストを返す
print(a[10:20])  # []

# 添字アクセスは例外
try:
    print(a[10])
except IndexError as e:
    print("IndexError:", e)
実行結果
[]
IndexError: list index out of range

スライスの書き方と省略記法

先頭から/末尾までの省略 [:end] [start:]

startendは省略できます。

省略された側は、それぞれ先頭または末尾が補われます。

Python
a = [10, 20, 30, 40, 50]
print(a[:3])   # 先頭から3要素: [10, 20, 30]
print(a[2:])   # 2番目以降すべて: [30, 40, 50]
実行結果
[10, 20, 30]
[30, 40, 50]

全体コピー list[:]

list[:]全体の浅いコピーを作ります。

元のリストとは別オブジェクトになります。

Python
a = [1, 2, 3]
b = a[:]   # 全体コピー
b.append(99)
print("a:", a)
print("b:", b)
print("同一オブジェクトか:", a is b)
実行結果
a: [1, 2, 3]
b: [1, 2, 3, 99]
同一オブジェクトか: False

負のインデックスで末尾基準 [-n:]

負のインデックスは末尾からの相対位置を表します。

例えば-1は末尾、-2は末尾の1つ前です。

Python
a = [10, 20, 30, 40, 50]
print(a[-2:])  # 末尾2件: [40, 50]
print(a[:-2])  # 末尾2件を除く: [10, 20, 30]
実行結果
[40, 50]
[10, 20, 30]

ステップ指定 list[start:end:step]

3番目のパラメータstepで、間引きや逆方向を指定できます。

正の値なら前方向、負の値なら逆方向に進みます。

Python
a = [0, 1, 2, 3, 4, 5, 6]
print(a[1:6:2])   # 1から5まで2刻み: [1, 3, 5]
print(a[5:1:-2])  # 5から2まで逆向き2刻み: [5, 3]
実行結果
[1, 3, 5]
[5, 3]

2件おきの取り出し [::2]

[::2]は配列全体から2件おきに取得します。

Python
a = list(range(10))  # 0〜9
print(a[::2])        # 偶数番インデックスの要素
実行結果
[0, 2, 4, 6, 8]

逆順の取り出し [::-1]

[::-1]簡単な反転です。

Python
a = [1, 2, 3, 4]
print(a[::-1])  # 逆順コピー
実行結果
[4, 3, 2, 1]

stepに0は不可

stepに0は指定できません

ValueErrorになります。

Python
a = [1, 2, 3]
try:
    print(a[::0])
except ValueError as e:
    print("ValueError:", e)
実行結果
ValueError: slice step cannot be zero

実践テクニックと注意点

スライスは新しいリストを返す(コピー)

スライスの結果は元とは別のリストです。

結果を変更しても元には影響しません。

Python
a = [10, 20, 30, 40]
b = a[1:3]     # [20, 30]
b[0] = 999     # bのみ変更
print("a:", a)
print("b:", b)
実行結果
a: [10, 20, 30, 40]
b: [999, 30]

スライス代入で部分更新・挿入・削除

スライスは「取得」だけでなく代入で更新や挿入、削除にも使えます。

Python
a = [10, 20, 30, 40, 50]

# 部分更新: 2番目から3要素を置き換え
a[1:4] = [200, 300]      # 要素数が違ってもOK(短くなる)
print("更新:", a)         # [10, 200, 300, 50]

# 挿入: 幅0スライスに代入すると差し込みになる
a[2:2] = [777, 888]
print("挿入:", a)         # [10, 200, 777, 888, 300, 50]

# 削除: 空リストを代入、またはdelと組み合わせ
a[1:4] = []               # 200, 777, 888を削除
print("削除(代入):", a)
del a[-2:]                # 末尾2件を削除
print("削除(del):", a)
実行結果
更新: [10, 200, 300, 50]
挿入: [10, 200, 777, 888, 300, 50]
削除(代入): [10, 300, 50]
削除(del): [10]

浅いコピーの注意(ネストしたリスト)

スライスは浅いコピーです。

入れ子(ネスト)の内側オブジェクトは共有されます。

内側を書き換えると両方に影響します。

Python
nested = [[1, 2], [3, 4]]
copy1 = nested[:]          # 浅いコピー
copy1[0][0] = 999          # 内側のリストを変更
print("nested:", nested)
print("copy1 :", copy1)
実行結果
nested: [[999, 2], [3, 4]]
copy1 : [[999, 2], [3, 4]]

深いコピーが必要ならcopy.deepcopyを使います。

Python
import copy
nested = [[1, 2], [3, 4]]
deep = copy.deepcopy(nested)
deep[0][0] = 999
print("nested:", nested)
print("deep  :", deep)
実行結果
nested: [[1, 2], [3, 4]]
deep  : [[999, 2], [3, 4]]

添字アクセスとの違い(安全性と戻り値)

添字アクセススライスの主な違いは次の通りです。

使い方戻り値の型範囲外の挙動
a[i]要素(単一)IndexError[1,2,3][10]は例外
a[i:j]リスト空リストを返す[1,2,3][10:20][]

これにより、境界が不確かな場面ではスライスの方が安全に扱えます。

境界指定のコツ(lenと組み合わせる)

len(a)と組み合わせると、データ長が変わっても壊れにくいコードになります。

Python
a = [0, 1, 2, 3, 4, 5]
n = 3
print(a[:n])           # 先頭n件
print(a[-n:])          # 末尾n件
mid = len(a) // 2
window = 4
print(a[mid:mid+window])  # 中央から幅4件(足りなければ末尾まで)
実行結果
[0, 1, 2]
[3, 4, 5]
[3, 4, 5]

多次元リストのスライスの考え方

リストのリスト(2次元)でも、スライスは各次元ごとに適用します。

列方向の抽出は内側のリストに対してスライスする必要があります。

Python
m = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]

# 行スライス: 先頭2行
print(m[:2])

# 列スライス: 各行の1〜2列目を抽出(内側にスライス)
cols_1_2 = [row[0:2] for row in m]
print(cols_1_2)

# 行の逆順、隔行の取得
print(m[::-1])   # 行の逆順
print(m[::2])    # 0行目、2行目
実行結果
[[1, 2, 3], [4, 5, 6]]
[[1, 2], [4, 5], [7, 8]]
[[7, 8, 9], [4, 5, 6], [1, 2, 3]]
[[1, 2, 3], [7, 8, 9]]

よくある使い方と練習パターン

先頭n件・末尾n件を取り出す

よく使う抽出は、[:n][-n:]です。

不足しても例外にならず、存在する範囲だけが返ります。

Python
scores = [68, 72, 81, 90, 77]
n = 3
print("先頭n件:", scores[:n])
print("末尾n件:", scores[-n:])
実行結果
先頭n件: [68, 72, 81]
末尾n件: [81, 90, 77]

中央の部分列を切り出す

配列中央から幅wのウィンドウを取り出す例です。

偶数・奇数長どちらにも対応します。

Python
data = list(range(1, 11))  # 1〜10
w = 4
start = (len(data) - w) // 2  # 中央に揃える開始位置
print(data[start:start+w])
実行結果
[4, 5, 6, 7]

条件に合う範囲を抽出する(インデックス計算)

値の範囲など条件で区間を抜き出すには、開始と終了のインデックスを求めてからスライスします。

Python
times = [5, 8, 12, 15, 18, 20, 25]

# 10以上18以下の区間を抽出
lo, hi = 10, 18

# 開始位置: 最初にlo以上になるインデックス
start = next((i for i, v in enumerate(times) if v >= lo), len(times))

# 終了位置: 最初にhiを超えるインデックス(スライスのendは含まない)
end = next((i for i, v in enumerate(times) if v > hi), len(times))

print("抽出:", times[start:end])
実行結果
抽出: [12, 15, 18]

部分置換・一括削除(del + slice)

範囲の置換や削除は、スライス代入やdelと組み合わせると一発です。

Python
a = list("abcdefg")

# 文字列の一部置換(リストで扱う)
a[2:5] = list("XYZ")   # 'cde' → 'XYZ'
print("置換:", "".join(a))

# 一括削除: 先頭3件を削除
del a[:3]
print("削除:", "".join(a))
実行結果
置換: abXYZfg
削除: YZfg

逆順スライスでの処理([::-1])

[::-1]で逆順に走査すると、後方から安全に処理できる場面があります。

ここでは逆順で出力しつつ、元リストは保持する例です。

Python
words = ["alpha", "beta", "gamma", "delta"]

# 逆順に処理(元は不変)
for w in words[::-1]:
    print(w.upper())

print("元:", words)
実行結果
DELTA
GAMMA
BETA
ALPHA
元: ['alpha', 'beta', 'gamma', 'delta']

なお、要素の削除を伴う場合は、元リストを直接走査しながらremoveするのは危険です。

削除はdel a[i:j]や条件で新リストを作る方法を検討してください。

まとめ

スライスは安全で柔軟な部分取り出しを実現するPythonの重要機能です。

半開区間(右端は含まない)、省略記法、負のインデックス、ステップを理解すれば、抽出、反転、間引き、コピーまで幅広く対応できます。

さらに、スライス代入で更新・挿入・削除も直感的に行えます。

浅いコピーの性質や多次元リストでの取り扱いに注意しつつ、lenと組み合わせた境界指定[::-1]などの定番パターンを手に馴染ませてください。

スライスを使いこなすことで、リスト操作の可読性と堅牢性が大きく向上します。

この記事を書いた人
エーテリア編集部
エーテリア編集部

人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!