リストのスライス:部分リストを取り出す#

はじめに#

これまでにリストの基本や、要素を追加したり削除したりする方法を勉強しました。今回は、リストから好きな部分だけを取り出す「スライス」という便利な機能を学びます。パンをスライスするように、リストを切り取る方法だと考えてください。

リストの一部分だけが欲しい時は?#

例えば、買い物リストの最初の3つのアイテムだけが欲しい場合や、名簿の後半だけが欲しい場合があります。そんな時に役立つのがスライスです。

これまでの方法では、1つずつ要素を取り出して、新しいリストに入れていました。

>
fruits = ["りんご", "バナナ", "オレンジ", "ぶどう", "メロン", "パイナップル", "いちご"]

# インデックスを使って1つずつ取り出す場合
first_three = [fruits[0], fruits[1], fruits[2]]
print("最初の3つの果物:", first_three)
最初の3つの果物: ['りんご', 'バナナ', 'オレンジ']

これは少しの要素なら問題ありませんが、たくさんの要素を取り出したい場合は大変です。スライスを使えば、この作業がとても簡単になります。

スライスの基本的な使い方#

スライスはどこからどこまでの要素が欲しいのかを、角括弧[]の中に:(コロン)を使って指定します。

基本的な書き方は次の通りです。

リスト[開始位置:終了位置]

ただし1つ注意があります。終了位置の要素は含まれません。つまり、終了位置の手前まででストップします。

>
fruits = ["りんご", "バナナ", "オレンジ", "ぶどう", "メロン", "パイナップル", "いちご"]

# インデックス1から3までの要素を取り出す(バナナ、オレンジ、ぶどう)
selected_fruits = fruits[1:4]
print("選んだ果物:", selected_fruits)
選んだ果物: ['バナナ', 'オレンジ', 'ぶどう']

なぜ終了位置の要素が含まれないのでしょうか?これは料理のレシピで「3時間煮込む」と言われたら、3時間後にちょうど終わるのと同じです。終了位置はそこで止めるという合図なんです。この方法には2つのメリットがあります。

  1. 要素の個数が簡単に計算できます:終了位置 - 開始位置 = 要素の個数
  2. 0:33:6のように続けて指定すると、ちょうどぴったり区切れます(重なりも抜けもない)

開始位置と終了位置の省略#

スライスでは、開始位置や終了位置を省略することもできます。省略すると、それぞれ以下のように解釈されます。

  • 開始位置を省略:リストの先頭(インデックス0)から
  • 終了位置を省略:リストの末尾まで
>
fruits = ["りんご", "バナナ", "オレンジ", "ぶどう", "メロン", "パイナップル", "いちご"]

# 先頭から3つ目まで(最初の3つ)
first_three = fruits[:3]  # [0:3]と同じ意味です
print("最初の3つ:", first_three)

# 4つ目から最後まで
last_fruits = fruits[3:]  # [3:7]と同じ意味です
print("残りの果物:", last_fruits)

# すべての要素(コピーを作る)
all_fruits = fruits[:]  # 前回学んだ all_fruits.copy() や list(all_fruits) と同じ意味です
print("すべての果物:", all_fruits)
最初の3つ: ['りんご', 'バナナ', 'オレンジ']
残りの果物: ['ぶどう', 'メロン', 'パイナップル', 'いちご']
すべての果物: ['りんご', 'バナナ', 'オレンジ', 'ぶどう', 'メロン', 'パイナップル', 'いちご']

最後の例(fruits[:])は、リスト全体のコピーを作ります。これは前回学んだ copy() メソッドや list() 関数と同じです。

ステップを使ったスライス#

スライスでは、「1つおき」「2つおき」といった「要素を何個ずつ飛ばして取得するか」の指定もできます。

これには終了位置の後ろに「ステップ」という数字を指定します。

リスト[開始位置:終了位置:ステップ]
>
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 0から9までの偶数を取り出す(2つおき)
even_numbers = numbers[0:10:2]
print("偶数:", even_numbers)

# 0から9までの奇数を取り出す(1から始めて2つおき)
odd_numbers = numbers[1:10:2]
print("奇数:", odd_numbers)

# 3つおきに取り出す
every_third = numbers[::3]  # 全体から3つおき
print("3つおき:", every_third)
偶数: [0, 2, 4, 6, 8]
奇数: [1, 3, 5, 7, 9]
3つおき: [0, 3, 6, 9]

負のインデックスを使ったスライス#

前回学んだように、マイナスの数字を使うと、リストの後ろから数えることができます。これはスライスでも使えます。例えば、-1は最後の要素、-2は最後から2番目の要素という意味です。

>
fruits = ["りんご", "バナナ", "オレンジ", "ぶどう", "メロン", "パイナップル", "いちご"]

# 最後の2つの要素を取り出す
last_two = fruits[-2:]
print("最後の2つ:", last_two)

# 最後の要素を除くすべて
except_last = fruits[:-1]
print("最後以外:", except_last)

# 最初と最後の要素を除く(真ん中の部分)
middle = fruits[1:-1]
print("真ん中の部分:", middle)
最後の2つ: ['パイナップル', 'いちご']
最後以外: ['りんご', 'バナナ', 'オレンジ', 'ぶどう', 'メロン', 'パイナップル']
真ん中の部分: ['バナナ', 'オレンジ', 'ぶどう', 'メロン', 'パイナップル']

負のステップを使ったスライス(リストの反転)#

ステップに負の数を指定すると、リストを逆順に走査することができます。これを使ってリストを逆順にすることができます。

>
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# リストを逆順にする
reversed_numbers = numbers[::-1]
print("逆順:", reversed_numbers)

# 2つおきに逆順で取り出す
reversed_even_indices = numbers[::-2]
print("逆順に2つおき:", reversed_even_indices)
逆順: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
逆順に2つおき: [9, 7, 5, 3, 1]

[::-1] はリストを逆順にする簡単な方法です。「最初から最後まで、逆向きに1つずつ」という意味になります。

スライスの実用的な使い方#

スライスの便利な使い方をいくつか見ていきましょう。

1. データの一部だけを処理する#

大きなデータセットから一部だけを取り出して処理したいときに便利です。

>
# 大きなデータセット(例:月間売上データ)
monthly_sales = [120, 135, 144, 156, 147, 139, 128, 132, 141, 152, 146, 138]

# 1~3月(最初の3ヶ月)の売上を分析
first_quarter = monthly_sales[:3]
print("第1四半期(1~3月)の売上:", first_quarter)
print("第1四半期の平均売上:", sum(first_quarter) / len(first_quarter), "万円")

# 4~6月(次の3ヶ月)の売上を分析
second_quarter = monthly_sales[3:6]
print("第2四半期(4~6月)の売上:", second_quarter)
print("第2四半期の平均売上:", sum(second_quarter) / len(second_quarter), "万円")
第1四半期(1~3月)の売上: [120, 135, 144]
第1四半期の平均売上: 133.0 万円
第2四半期(4~6月)の売上: [156, 147, 139]
第2四半期の平均売上: 147.33333333333334 万円

ここで使っている sum() は、リストの中の数値をすべて合計してくれる便利な関数です。例えば、sum([1, 2, 3]) とすると 6(= 1 + 2 + 3)という結果になります。

2. リストのコピーを作成してから変更する#

元のリストを変更せずに、コピーを作成して操作したい場合に便利です。

>
original = ["a", "b", "c", "d", "e"]
print("元のリスト:", original)

# コピーを作成して変更
copy_list = original[:]
copy_list[0] = "X"
copy_list[1] = "Y"

print("変更後の元のリスト:", original)  # 変更されていない
print("変更されたコピー:", copy_list)   # 変更されている
元のリスト: ['a', 'b', 'c', 'd', 'e']
変更後の元のリスト: ['a', 'b', 'c', 'd', 'e']
変更されたコピー: ['X', 'Y', 'c', 'd', 'e']

スライスを使ってリストを変更する#

スライスは要素の取り出しだけでなく、リストの一部を置き換えることもできます。

>
letters = ["a", "b", "c", "d", "e", "f", "g"]
print("元のリスト:", letters)

# 真ん中の3つの要素(c, d, e)をXYZに置き換える
letters[2:5] = ["X", "Y", "Z"]
print("置き換え後:", letters)

# 2つの要素を4つの要素に置き換える(増える)
letters[1:3] = ["P", "Q", "R", "S"]
print("要素が増えた後:", letters)

# 残りすべてを1つの要素に置き換える(減る)
letters[4:] = ["END"]
print("要素が減った後:", letters)
元のリスト: ['a', 'b', 'c', 'd', 'e', 'f', 'g']
置き換え後: ['a', 'b', 'X', 'Y', 'Z', 'f', 'g']
要素が増えた後: ['a', 'P', 'Q', 'R', 'S', 'Y', 'Z', 'f', 'g']
要素が減った後: ['a', 'P', 'Q', 'R', 'END']

スライスを使って要素を削除することもできます。削除したい部分を空のリスト[]に置き換えるだけです。

>
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print("元のリスト:", numbers)

# 真ん中の4, 5, 6, 7を削除
numbers[3:7] = []
print("削除後:", numbers)
元のリスト: [1, 2, 3, 4, 5, 6, 7, 8, 9]
削除後: [1, 2, 3, 8, 9]

まとめ#

今回はリストのスライスについて学びました。

  • スライスは料理を切り分けるように、リストの一部を取り出す方法です
  • 基本的には リスト[開始:終了] の形で使います(終了位置の手前まで取り出されます)
  • 開始や終了を省略すると、それぞれリストの最初か最後になります
  • リスト[開始:終了:ステップ] の形にすると、飛ばし飛ばしで取り出せます
  • 負の数を使うと、リストの後ろから数えることができます
  • [::-1] でリスト全体を逆順にできます
  • スライスを使って、リストの一部を置き換えたり削除したりもできます

スライスを使いこなせば、データの一部を簡単に取り出せるようになります。特に大きなデータを扱う時に便利な機能です。日常的なプログラミングでよく使う技術なので、ぜひ練習してみてください。