Pythonで複数のデータを順番に管理する場合、リスト(list)を使います。
本記事では、リストから特定の位置の要素を取り出す方法(インデックスアクセス)に絞って、基本から実用的なテクニック、さらにエラーを避ける安全な書き方まで、初心者の方にも分かりやすく解説します。
Pythonのリストのインデックス入門
インデックスとは 0から始まる番号
リストの各要素には位置を示す番号が付いており、これをインデックスと呼びます。
Pythonでは最初の要素がインデックス0、次が1というように、0から始まる(0-origin)のが特徴です。
末尾から数える場合は負のインデックスを使い、最後の要素は-1、最後から2番目は-2というように指定できます。
インデックスで要素を取得する基本構文
基本構文はリスト[インデックス]
です。
インデックスは整数で指定します。
# 基本のリスト
fruits = ["apple", "banana", "cherry", "date"]
# インデックスで要素を取得
second = fruits[1] # 2番目の要素(インデックス1)
third = fruits[2] # 3番目の要素(インデックス2)
print(second)
print(third)
banana
cherry
先頭と末尾の要素を取得する
先頭はインデックス0、末尾はインデックス-1で取得します。
fruits = ["apple", "banana", "cherry", "date"]
first = fruits[0] # 先頭
last = fruits[-1] # 末尾
print(f"先頭: {first}")
print(f"末尾: {last}")
先頭: apple
末尾: date
正のインデックスと負のインデックスの使い分け
前から数えて要素を取得する
前から順番に数えるときは正のインデックスを使います。
range(len(リスト))
と組み合わせると、すべての位置を順に処理できます。
fruits = ["apple", "banana", "cherry", "date"]
# 0からlen(fruits)-1まで前から数える
for i in range(len(fruits)):
print(f"{i}: {fruits[i]}")
0: apple
1: banana
2: cherry
3: date
後ろから数えて要素を取得する
末尾から数えるときは負のインデックスを使います。
最後が-1、その前が-2です。
fruits = ["apple", "banana", "cherry", "date"]
# 末尾から-1, -2, ... と遡って取得
for i in range(1, len(fruits) + 1):
print(f"{-i}: {fruits[-i]}")
-1: date
-2: cherry
-3: banana
-4: apple
負のインデックスは、リストの長さを知らなくても末尾側の要素に素早くアクセスできる点が便利です。
以下は同じリストに対する正・負インデックスと要素の対応表です。
要素 | 正のインデックス | 負のインデックス |
---|---|---|
apple | 0 | -4 |
banana | 1 | -3 |
cherry | 2 | -2 |
date | 3 | -1 |
インデックスの範囲とlenで確認する
有効なインデックスの範囲は-len(lst)
以上かつlen(lst)-1
以下です。
つまり-len(lst) <= idx < len(lst)
を満たす必要があります。
len()
で長さを調べると安全に判断できます。
fruits = ["apple", "banana", "cherry", "date"]
n = len(fruits)
test_indices = [-5, -4, -1, 0, 3, 4]
for idx in test_indices:
in_range = (-n <= idx < n) # 有効範囲の判定
result = fruits[idx] if in_range else "範囲外なので未取得"
print(f"idx={idx:>2} | 有効? {in_range} | 取得結果: {result}")
idx=-5 | 有効? False | 取得結果: 範囲外なので未取得
idx=-4 | 有効? True | 取得結果: apple
idx=-1 | 有効? True | 取得結果: date
idx= 0 | 有効? True | 取得結果: apple
idx= 3 | 有効? True | 取得結果: date
idx= 4 | 有効? False | 取得結果: 範囲外なので未取得
位置で取得する実用パターン
インデックスを変数で指定して取得
インデックスは変数で持っておくと便利です。
ユーザー入力など外部から受け取った値を整数に変換し、範囲チェックしてから使います。
fruits = ["apple", "banana", "cherry", "date"]
# 例: 変数で指定
idx = 2
print(f"idx={idx} の要素: {fruits[idx]}")
# 例: ユーザー入力(ここでは固定文字列を想定)
index_str = "3" # 実際は input("インデックスを入力: ")
index_int = int(index_str) # 文字列を整数に変換
# 範囲チェックをしてからアクセス
if -len(fruits) <= index_int < len(fruits):
print(f"入力idx={index_int} の要素: {fruits[index_int]}")
else:
print("入力インデックスが範囲外です。")
idx=2 の要素: cherry
入力idx=3 の要素: date
ネストしたリストから位置で取得
リストの中にリストが入っている(二次元配列のような)場合は、[行のインデックス][列のインデックス]
のように2回[]
を並べてアクセスします。
# 3x3の表をリストのリストで表現
table = [
["Mon", "Tue", "Wed"],
["Thu", "Fri", "Sat"],
["Sun", "Hol", "N/A"],
]
# 行と列を組み合わせて取得
print("table[1][2]:", table[1][2]) # 2行目・3列目 → "Sat"
print("table[0][0]:", table[0][0]) # 1行目・1列目 → "Mon"
print("table[-1][-3]:", table[-1][-3]) # 最終行の先頭 → "Sun"
table[1][2]: Sat
table[0][0]: Mon
table[-1][-3]: Sun
複数の位置の要素をまとめて取得
Pythonの標準的なリストインデックスは「1つの位置」しか受け取れませんが、インデックスのリストを用意して内包表記でまとめて取り出せます。
fruits = ["apple", "banana", "cherry", "date", "elderberry"]
indices = [0, 2, -1] # 取り出したい位置の一覧
picked = [fruits[i] for i in indices] # それぞれを取り出して新しいリストに
print(picked)
['apple', 'cherry', 'elderberry']
範囲外のインデックスが混じる可能性があるなら、len()
でチェックしてから拾うようにすると安全です。
fruits = ["apple", "banana", "cherry", "date", "elderberry"]
indices = [0, 2, -1, 99, -10] # 99や-10は範囲外
n = len(fruits)
safe_picked = [fruits[i] for i in indices if -n <= i < n]
print(safe_picked) # 範囲外はスキップ
['apple', 'cherry', 'elderberry']
補足: operator.itemgetterで一度に取得(中級者向け)
operator.itemgetter
を使うと、複数のインデックスをまとめて指定できます。
戻り値はタプルです。
from operator import itemgetter
fruits = ["apple", "banana", "cherry", "date", "elderberry"]
elements = itemgetter(0, 2, -1)(fruits) # 0番目, 2番目, 末尾
print(elements, type(elements))
('apple', 'cherry', 'elderberry') <class 'tuple'>
エラー対策と安全な取得
範囲外のIndexErrorを防ぐ
存在しない位置を指定するとIndexError
が発生します。
以下はエラー例です。
fruits = ["apple", "banana", "cherry", "date"]
print(fruits[10]) # 4要素のリストに10番目は存在しない
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
IndexError: list index out of range
実運用では、範囲チェックまたは例外処理で防ぎます。
# 1) 範囲チェックで防ぐ
def safe_get(seq, idx, default=None):
n = len(seq)
if -n <= idx < n:
return seq[idx]
return default
fruits = ["apple", "banana", "cherry", "date"]
print(safe_get(fruits, 10, default="(なし)")) # 範囲外 → デフォルト値
print(safe_get(fruits, -1, default="(なし)")) # 範囲内 → 末尾
(なし)
date
# 2) 例外処理(try-except)で受け止める
fruits = ["apple", "banana", "cherry", "date"]
try:
item = fruits[10]
except IndexError:
item = "(なし)"
print(item)
(なし)
用途や好みに応じて、事前チェックと例外処理を使い分けます。
繰り返しアクセスする処理では事前チェック、単発で失敗を例外として扱いたい場合はtry-exceptが向いています。
整数以外のインデックスによるTypeErrorに注意
インデックスは整数でなければなりません。
浮動小数点数や文字列を使うとTypeError
になります。
fruits = ["apple", "banana", "cherry", "date"]
print(fruits[1.0]) # 小数(float)は不可
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
TypeError: list indices must be integers or slices, not float
fruits = ["apple", "banana", "cherry", "date"]
print(fruits["2"]) # 文字列は不可
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
TypeError: list indices must be integers or slices, not str
なお、True
やFalse
は整数扱い(それぞれ1と0)になるため、意図せずインデックスとして動作してしまいます。
混乱を防ぐため、インデックスにブール値を直接使うのは避けるのが無難です。
fruits = ["apple", "banana", "cherry", "date"]
print(f"Trueは1として扱われます -> fruits[True] = {fruits[True]}") # 実質fruits[1]
print(f"Falseは0として扱われます -> fruits[False] = {fruits[False]}") # 実質fruits[0]
Trueは1として扱われます -> fruits[True] = banana
Falseは0として扱われます -> fruits[False] = apple
まとめ
本記事では、Pythonのリストから特定の位置の要素を取り出す方法を、正負のインデックス、基本構文、実用的な取得パターン、そしてエラー対策まで段階的に解説しました。
要点は次の通りです。
- 0始まりのインデックスで先頭は0、末尾は-1。
- 範囲は
-len(lst) <= idx < len(lst)
が有効。
複数位置の取得は内包表記やitemgetter
でまとめやすく、範囲外や型の誤りは事前チェックや例外処理で安全に扱えます。
まずは小さなリストでインデックス指定に慣れ、徐々にネストしたリストや複数位置の取得に応用していくと理解が深まります。