こんにちは、かつコーチです。
Pythonのスライスは、リストの基本操作としてlist[1:3]のような書き方をすでに使っている方も多いと思います。
ただ、スライスには[start:stop:step]という第3の要素があることをご存じでしょうか。
「リストを逆順にしたい」
「1つおきに要素を取り出したい」
こうした処理は、実はスライス1行で書けてしまいます。
この記事では、スライスの応用的な書き方を実例とともに解説します。
読み終える頃には、ループを書かずにスライスだけでリスト操作を完結できるようになります。
[start:stop:step]の詳細を理解する
スライスの基本構文を復習する
スライスとは、リストや文字列などのシーケンスから一部分を取り出す機能です。
基本の形はlist[start:stop]で、startからstopの1つ手前までを取得します。
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(numbers[2:5])
実行結果は次の通りです。
[2, 3, 4]
stepを指定して間隔を変える
スライスには3つ目の要素としてstep(間隔)を指定できます。
書き方はlist[start:stop:step]です。
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(numbers[0:10:2])
実行結果は次の通りです。
[0, 2, 4, 6, 8]
stepに2を指定すると、1つおきに要素が取り出されます。
startとstopを省略する
startやstopは省略できます。
省略すると、それぞれ「先頭から」「末尾まで」を意味します。
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(numbers[::2])
print(numbers[3:])
print(numbers[:5])
実行結果は次の通りです。
[0, 2, 4, 6, 8]
[3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4]
[::2]のようにstartとstopを両方省略すると、リスト全体を対象にstepだけを適用できます。
リストを逆順にする[::-1]の実例
stepに負の数を指定する
stepには負の数も指定できます。
負の数を指定すると、末尾から先頭に向かって要素を取得します。
代表的なのが[::-1]で、リスト全体を逆順に取得できます。
numbers = [1, 2, 3, 4, 5]
reversed_numbers = numbers[::-1]
print(reversed_numbers)
実行結果は次の通りです。
[5, 4, 3, 2, 1]
reverse()メソッドと違い、[::-1]は元のリストを変更せず、新しいリストを返す点がポイントです。
文字列の逆順にも使える
[::-1]はリストだけでなく、文字列にもそのまま使えます。
text = "かつコーチ"
print(text[::-1])
実行結果は次の通りです。
チーコつか
回文判定(前から読んでも後ろから読んでも同じ文字列かの判定)などで、よく使われるテクニックです。
逆順+間引きを組み合わせる
start・stop・stepはすべて同時に指定できます。
負のstepと組み合わせれば、逆順にしながら間引くことも可能です。
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(numbers[8:2:-2])
実行結果は次の通りです。
[8, 6, 4]
8から2の1つ手前(つまり3)まで、2つずつ逆方向に進みながら取得しています。
間引き取得の実例:3つおきにデータを取得する
CSVから読み込んだ大量データの中から、一定間隔でサンプリングしたい場面があります。
そんなときもstepを指定するだけで実現できます。
sales_data = [120, 135, 98, 150, 200, 175, 160, 190, 140, 210]
# 3件おきにサンプリングする
sampled = sales_data[::3]
print(sampled)
実行結果は次の通りです。
[120, 150, 160, 210]
グラフ描画用に間引いたデータを作りたいときなど、実務でも使う場面が多いテクニックです。
よくあるつまずきポイント・エラー対処
stepに0を指定してエラーになる
筆者が実際につまずいたのが、stepに0を指定してしまうケースです。
「stepを大きくすれば間隔が広がる」という発想から、うっかり0を渡してしまったことがありました。
❌ Before(エラーになる書き方)
numbers = [0, 1, 2, 3, 4, 5]
print(numbers[::0])
実行すると、次のエラーメッセージが表示されます。
ValueError: slice step cannot be zero
stepは「何個ずつ進むか」を表すため、0だと永遠に進めず、Pythonがエラーとして弾いてくれます。
✅ After(正しい書き方)
numbers = [0, 1, 2, 3, 4, 5]
print(numbers[::1])
stepを省略するか1以上(逆順なら-1以下)を指定すれば、エラーは解消します。
インデックスの範囲外を指定しても落ちない点に注意する
通常のlist[10]のようなインデックス指定では、範囲外を指定するとIndexErrorが発生します。
一方、スライスは範囲外を指定してもエラーにならず、取得できる範囲だけを返してくれます。
numbers = [0, 1, 2, 3, 4]
print(numbers[2:100])
実行結果は次の通りです。
[2, 3, 4]
これは便利な仕様である一方、「範囲外を指定しているのにエラーが出ないから気づかない」というバグの温床にもなります。
意図したデータ数が本当に取れているか、len()で確認する習慣をつけると安心です。
まとめ
この記事のポイント
- スライスは
[start:stop:step]の3要素で構成される stepを指定すると間引き取得ができる[::-1]でリストや文字列を逆順にできるstepに0を指定するとValueErrorになる- スライスは範囲外を指定してもエラーにならないため注意が必要
次に読むべき記事
- リストの基本:作成・追加・削除・スライス
- sorted()とsort()でリストを並び替える
- リスト内包表記の書き方と使いどころ
タグ: Python, 中級者向け, 基本文法