【Python】「IndexError:list index out of range」とは?原因や例外処理する方法

Pythonプログラミングを学んでいると、 IndexError: list index out of range というエラーメッセージに出会うことがあるかもしれません。

このエラーは、リストやタプルなどのデータに対して無効なインデックスを指定したときに発生します。

本記事では、このエラーの原因や具体例、そしてエラーを防ぐための方法や例外処理の方法について、初心者にもわかりやすく解説します。

目次から探す

IndexErrorの定義

IndexErrorは、Pythonの組み込み例外の一つで、シーケンス型データ(リスト、タプル、文字列など)に対して無効なインデックスを指定したときに発生します。

具体的には、存在しないインデックスを参照しようとした場合にこのエラーが発生します。

例えば、リストの長さが5である場合、有効なインデックスは0から4までです。

この範囲外のインデックス(例えば5や-6)を指定すると、IndexErrorが発生します。

IndexErrorが発生する状況

IndexErrorが発生する具体的な状況をいくつか挙げてみましょう。

リストの長さを超えるインデックス

リストの長さを超えるインデックスを指定すると、IndexErrorが発生します。

以下の例を見てください。

my_list = [1, 2, 3, 4, 5]
print(my_list[5])  # IndexError: list index out of range

この例では、リストの長さは5ですが、有効なインデックスは0から4までです。

インデックス5を指定すると、範囲外のアクセスとなり、IndexErrorが発生します。

負のインデックスの誤用

Pythonでは負のインデックスを使用してリストの末尾から要素を参照することができますが、負のインデックスがリストの範囲外になるとIndexErrorが発生します。

my_list = [1, 2, 3, 4, 5]
print(my_list[-6])  # IndexError: list index out of range

この例では、リストの長さは5で、有効な負のインデックスは-1から-5までです。

インデックス-6を指定すると、範囲外のアクセスとなり、IndexErrorが発生します。

空のリストへのアクセス

空のリストに対してインデックスを指定すると、必ずIndexErrorが発生します。

empty_list = []
print(empty_list[0])  # IndexError: list index out of range

この例では、リストが空であるため、どのインデックスを指定しても範囲外のアクセスとなり、IndexErrorが発生します。

以上のように、IndexErrorはリストやタプルなどのシーケンス型データに対して無効なインデックスを指定したときに発生します。

次のセクションでは、具体的な例を通じてこのエラーの原因をさらに詳しく見ていきます。

list index out of rangeの原因

インデックスの範囲外アクセス

Pythonでリストを操作する際に、リストのインデックスが範囲外になると IndexError: list index out of range というエラーが発生します。

このエラーは、リストの要素にアクセスしようとしたときに、そのインデックスがリストの範囲内にない場合に発生します。

以下に、具体的な原因をいくつか紹介します。

リストの長さを超えるインデックス

リストの長さを超えるインデックスにアクセスしようとすると、このエラーが発生します。

例えば、リストの長さが5の場合、有効なインデックスは0から4までです。

インデックス5以上にアクセスしようとするとエラーになります。

# リストの定義
my_list = [1, 2, 3, 4, 5]
# インデックス5にアクセスしようとする(リストの長さは5なので範囲外)
print(my_list[5])  # IndexError: list index out of range

負のインデックスの誤用

Pythonでは負のインデックスを使ってリストの末尾から要素にアクセスすることができます。

しかし、負のインデックスがリストの範囲外になるとエラーが発生します。

例えば、リストの長さが3の場合、有効な負のインデックスは-1から-3までです。

-4以下のインデックスにアクセスしようとするとエラーになります。

# リストの定義
my_list = [1, 2, 3]
# 負のインデックス-4にアクセスしようとする(リストの長さは3なので範囲外)
print(my_list[-4])  # IndexError: list index out of range

空のリストへのアクセス

空のリストに対してインデックスを指定してアクセスしようとすると、必ず IndexError: list index out of range が発生します。

空のリストには要素が一つもないため、どのインデックスも範囲外となります。

# 空のリストの定義
empty_list = []
# インデックス0にアクセスしようとする(リストは空なので範囲外)
print(empty_list[0])  # IndexError: list index out of range

これらの原因を理解することで、 IndexError: list index out of range を避けるための対策を講じることができます。

次のセクションでは、このエラーを例外処理する方法について詳しく説明します。

list index out of rangeの具体例

基本的な例

まずは、基本的な例を見てみましょう。

以下のコードは、リストの範囲外のインデックスにアクセスしようとすることで IndexError: list index out of range が発生します。

# リストの定義
my_list = [1, 2, 3]
# 範囲外のインデックスにアクセス
print(my_list[3])

このコードを実行すると、以下のエラーメッセージが表示されます。

IndexError: list index out of range

リスト my_list のインデックスは 0 から 2 までしか存在しないため、インデックス 3 にアクセスしようとするとエラーが発生します。

ループ内での例

次に、ループ内で IndexError が発生する例を見てみましょう。

以下のコードは、リストの要素を順番に処理するループですが、誤って範囲外のインデックスにアクセスしています。

# リストの定義
my_list = [1, 2, 3]
# インデックスを使ったループ
for i in range(4):
    print(my_list[i])

このコードを実行すると、以下のエラーメッセージが表示されます。

1
2
3
IndexError: list index out of range

ループの範囲がリストの長さを超えているため、インデックス 3 にアクセスしようとした時点でエラーが発生します。

関数内での例

最後に、関数内で IndexError が発生する例を見てみましょう。

以下のコードは、リストの特定のインデックスの要素を返す関数ですが、範囲外のインデックスにアクセスしようとしています。

# リストの定義
my_list = [1, 2, 3]
# 特定のインデックスの要素を返す関数
def get_element(index):
    return my_list[index]
# 範囲外のインデックスを指定
print(get_element(3))

このコードを実行すると、以下のエラーメッセージが表示されます。

IndexError: list index out of range

関数 get_element に渡されたインデックスがリストの範囲外であるため、エラーが発生します。

これらの具体例を通じて、IndexError: list index out of range がどのように発生するかを理解できたと思います。

次に、これらのエラーを防ぐ方法や例外処理の方法について詳しく見ていきましょう。

例外処理の方法

Pythonでは、プログラムの実行中に発生するエラーを「例外」と呼びます。

例外が発生すると、プログラムは通常その場で停止しますが、例外処理を行うことでプログラムの停止を防ぎ、適切な対応を行うことができます。

ここでは、IndexErrorを含む例外処理の方法について解説します。

try-except文の基本

例外処理を行うための基本的な構文はtry-except文です。

tryブロック内に例外が発生する可能性のあるコードを記述し、exceptブロック内に例外が発生した場合の処理を記述します。

try:
    # 例外が発生する可能性のあるコード
except:
    # 例外が発生した場合の処理

IndexErrorをキャッチする方法

基本的なtry-except文

IndexErrorをキャッチするためには、exceptブロックでIndexErrorを指定します。

これにより、リストのインデックスが範囲外になった場合に適切な処理を行うことができます。

my_list = [1, 2, 3]
try:
    print(my_list[3])  # ここでIndexErrorが発生する
except IndexError:
    print("インデックスが範囲外です")

上記のコードでは、my_list[3]が範囲外のインデックスを参照しているため、IndexErrorが発生します。

しかし、except IndexErrorブロックがこの例外をキャッチし、「インデックスが範囲外です」というメッセージを表示します。

複数の例外をキャッチする方法

複数の例外をキャッチする場合は、exceptブロックを複数記述するか、タプルを使って一つのexceptブロックで複数の例外を指定することができます。

my_list = [1, 2, 3]
try:
    print(my_list[3])  # ここでIndexErrorが発生する
except (IndexError, ValueError):
    print("インデックスが範囲外か、値のエラーです")

上記のコードでは、IndexErrorValueErrorの両方をキャッチするようにしています。

例外処理の具体例

シンプルな例

以下は、シンプルな例外処理の例です。

リストのインデックスが範囲外の場合にエラーメッセージを表示します。

my_list = [1, 2, 3]
try:
    print(my_list[3])  # ここでIndexErrorが発生する
except IndexError:
    print("インデックスが範囲外です")

ループ内での例

ループ内で例外処理を行う場合、特定のインデックスが範囲外になったときにエラーメッセージを表示し、ループを続行することができます。

my_list = [1, 2, 3]
for i in range(5):
    try:
        print(my_list[i])
    except IndexError:
        print(f"インデックス {i} が範囲外です")

上記のコードでは、range(5)で0から4までのインデックスを試みますが、my_listは3つの要素しか持たないため、インデックス3と4でIndexErrorが発生します。

これにより、エラーメッセージが表示されます。

関数内での例

関数内で例外処理を行う場合、関数が呼び出されたときに例外が発生しても、適切に処理することができます。

def get_element(my_list, index):
    try:
        return my_list[index]
    except IndexError:
        return "インデックスが範囲外です"
my_list = [1, 2, 3]
print(get_element(my_list, 3))  # インデックスが範囲外です

上記のコードでは、get_element関数がリストとインデックスを受け取り、範囲外のインデックスが指定された場合にエラーメッセージを返します。

予防策

IndexErrorを避けるためには、いくつかの予防策を講じることが重要です。

以下に、リストの長さを確認する方法、負のインデックスの正しい使い方、リストが空でないことを確認する方法について詳しく説明します。

リストの長さを確認する

リストのインデックスにアクセスする前に、そのリストの長さを確認することで、IndexErrorを防ぐことができます。

Pythonでは、len()関数を使ってリストの長さを取得できます。

my_list = [1, 2, 3, 4, 5]
# インデックスがリストの長さ以内か確認
index = 5
if index < len(my_list):
    print(my_list[index])
else:
    print("インデックスが範囲外です")

このコードでは、インデックスがリストの長さ以内であるかを確認し、範囲外の場合にはエラーメッセージを表示します。

負のインデックスの正しい使い方

Pythonでは、負のインデックスを使ってリストの末尾から要素にアクセスすることができます。

しかし、負のインデックスを誤って使用すると、IndexErrorが発生する可能性があります。

負のインデックスを使用する際には、リストの長さを考慮することが重要です。

my_list = [1, 2, 3, 4, 5]
# 負のインデックスを使用してリストの末尾から要素にアクセス
index = -1
if -len(my_list) <= index < len(my_list):
    print(my_list[index])
else:
    print("インデックスが範囲外です")

このコードでは、負のインデックスがリストの範囲内であるかを確認し、範囲外の場合にはエラーメッセージを表示します。

リストが空でないことを確認する

リストが空である場合にインデックスにアクセスしようとすると、IndexErrorが発生します。

リストが空でないことを確認することで、このエラーを防ぐことができます。

my_list = []
# リストが空でないことを確認
if my_list:
    print(my_list[0])
else:
    print("リストが空です")

このコードでは、リストが空でないことを確認し、空の場合にはエラーメッセージを表示します。

これらの予防策を実践することで、IndexErrorを効果的に回避することができます。

リストの操作を行う際には、常にこれらのポイントを念頭に置いておくことが重要です。

デバッグの方法

プログラムが思い通りに動かない場合、デバッグは非常に重要です。

特に IndexError: list index out of range のようなエラーは、デバッグを通じて原因を特定し、修正することができます。

ここでは、デバッグの基本的な方法として「print文を使ったデバッグ」と「デバッガを使ったデバッグ」の2つを紹介します。

print文を使ったデバッグ

print文を使ったデバッグは、最も基本的で手軽な方法です。

プログラムの特定の箇所にprint文を挿入して、変数の値やプログラムの進行状況を確認します。

以下のコードは、リストの要素にアクセスする際に IndexError: list index out of range が発生する例です。

numbers = [1, 2, 3, 4, 5]
for i in range(6):
    print(numbers[i])

このコードを実行すると、次のようなエラーが発生します。

IndexError: list index out of range

このエラーをデバッグするために、print文を使って変数iの値を確認します。

numbers = [1, 2, 3, 4, 5]
for i in range(6):
    print(f"i = {i}")  # 変数iの値を出力
    print(numbers[i])

このようにすることで、エラーが発生する前にiの値が何であるかを確認できます。

実行結果は次のようになります。

i = 0
1
i = 1
2
i = 2
3
i = 3
4
i = 4
5
i = 5
IndexError: list index out of range

この結果から、iが5のときにエラーが発生していることがわかります。

リストnumbersのインデックスは0から4までなので、5は範囲外です。

デバッガを使ったデバッグ

print文を使ったデバッグは手軽ですが、複雑なプログラムでは効率が悪くなることがあります。

そんなときには、デバッガを使うと便利です。

Pythonには標準でpdbというデバッガが用意されています。

先ほどの例をデバッガを使ってデバッグしてみましょう。

import pdb
numbers = [1, 2, 3, 4, 5]
for i in range(6):
    pdb.set_trace()  # デバッガを起動
    print(numbers[i])

このコードを実行すると、デバッガが起動し、インタラクティブなデバッグセッションが開始されます。

> <stdin>(6)<module>()
-> print(numbers[i])
(Pdb)

デバッガのプロンプト(Pdb)が表示されたら、以下のコマンドを使ってデバッグを進めます。

  • n (next): 次の行に進む
  • c (continue): ブレークポイントまで実行を続ける
  • p <変数名>: 変数の値を表示する

例えば、iの値を確認するには、p iと入力します。

(Pdb) p i
0

このようにして、変数の値やプログラムの進行状況を詳細に確認できます。

デバッガを使うことで、プログラムの実行を一時停止し、変数の状態や実行フローを詳細に調査することができます。

これにより、エラーの原因を迅速に特定し、修正することが可能です。

以上が、print文を使ったデバッグとデバッガを使ったデバッグの基本的な方法です。

どちらの方法も使いこなすことで、効率的にプログラムの問題を解決できるようになります。

目次から探す