Pythonのリストから特定の位置の要素を取り出すには、list[i]
という単純な構文を使います。
インデックスは0から始まり、負の数で末尾からも数えられるため、最初と最後の要素を直感的に取得できます。
本記事では初心者の方に向けて、基礎からエラーの回避、よく使うパターン、ネストしたリストまで順序立てて解説します。
リスト要素を位置で取得する基本(インデックス)
インデックスは0始まり(0-based)
Pythonのリストは0から数えます。
つまり1番目の要素はインデックス0、2番目は1です。
負のインデックスでは末尾から数え、-1
が最後、-2
が最後から2番目です。
この規則を覚えると、先頭と末尾の操作が簡単になります。
以下のリストを例にします。
fruits = ["apple", "banana", "cherry", "date"]
インデックスと要素の対応は次の通りです。
インデックス | 要素 | 説明 |
---|---|---|
0 | “apple” | 1番目 |
1 | “banana” | 2番目 |
2 | “cherry” | 3番目 |
3 | “date” | 4番目 |
-1 | “date” | 最後 |
-2 | “cherry” | 最後から2番目 |
-3 | “banana” | 最後から3番目 |
-4 | “apple” | 最後から4番目 |
有効な範囲はリストの長さに依存し、正は0以上長さ未満、負はマイナス長さ以上-1以下です。
要素を取り出す構文 list[i]
基本はlist[i]
です。
括弧は角括弧[]
を使います。
インデックスは整数で指定します。
# 基本の取り出し
fruits = ["apple", "banana", "cherry", "date"]
print(fruits[0]) # 0番目(=1番目)の要素
print(fruits[1]) # 1番目(=2番目)の要素
i = 2 # 変数で指定してもOK
print(fruits[i]) # 2番目(=3番目)の要素
apple
banana
cherry
プログラムでは数値計算の都合で0始まりが一般的であり、Pythonもこのルールに従います。
1番目/2番目/n番目の要素を取得
人間の言い方(1番目、2番目、n番目)をプログラムの0始まりに対応させるには、n番目はインデックスn-1
と覚えるのが近道です。
fruits = ["apple", "banana", "cherry", "date"]
# 1番目と2番目
first = fruits[0] # 1番目
second = fruits[1] # 2番目
# n番目を関数で表現(単純版: 範囲外は未対処)
def nth(lst, n):
# nは1以上を想定。nが1ならlst[0]を返す
return lst[n - 1]
print(nth(fruits, 3)) # 3番目
cherry
注意: 範囲外のnを渡すとIndexError
になります。
範囲チェックは後述します。
負のインデックスで末尾から取得(-1,-2)
最後の要素は-1
、最後から2番目は-2
で簡単に取得できます。
これによりリストの長さを調べずに末尾にアクセス可能です。
fruits = ["apple", "banana", "cherry", "date"]
print(fruits[-1]) # 最後
print(fruits[-2]) # 最後から2番目
date
cherry
インデックスの範囲とエラー(IndexError)
有効なインデックス範囲
長さn
のリストに対し、正のインデックスは0
以上n-1
以下、負のインデックスは-n
以上-1
以下が有効です。
この範囲を超えると例外が起きます。
範囲外アクセスでIndexError
範囲外のアクセスはIndexError
になります。
エラーメッセージは「list index out of range」です。
nums = [10, 20, 30]
# 範囲外アクセスの発生例
try:
print(nums[3]) # 有効範囲は0,1,2のみ
except Exception as e:
print(type(e).__name__, str(e))
IndexError list index out of range
エラーはプログラムの途中で停止を引き起こすため、事前に回避するのが基本です。
IndexErrorを避ける基本(範囲チェック)
最も確実なのはlen()
で範囲をチェックすることです。
正負の両方に対応するシンプルな関数を示します。
from typing import Any, Optional
def safe_get(lst: list, i: int, default: Optional[Any] = None) -> Any:
"""リストlstからインデックスiの要素を安全に取得。範囲外ならdefaultを返す。"""
n = len(lst)
# 正のインデックスの範囲チェック
if 0 <= i < n:
return lst[i]
# 負のインデックスの範囲チェック
if -n <= i < 0:
return lst[i]
return default
fruits = ["apple", "banana", "cherry", "date"]
print(safe_get(fruits, 2)) # 有効(2→"cherry")
print(safe_get(fruits, -1)) # 有効(-1→"date")
print(safe_get(fruits, 99, "?")) # 範囲外→デフォルト("?")
cherry
date
?
要件によってはtry/except
で補足する方法も有効です。
def safe_get_try(lst: list, i: int, default=None):
try:
return lst[i]
except IndexError:
return default
- 関連記事:len()でリストの長さを取得する
- 関連記事:try-exceptで例外処理を実装する
整数以外のインデックスはTypeError
リストのインデックスは整数のみで、浮動小数や文字列はTypeError
になります。
nums = [10, 20, 30]
try:
print(nums[1.0]) # 浮動小数は不可
except Exception as e:
print(type(e).__name__, str(e))
TypeError list indices must be integers or slices, not float
小数や文字列を使いたい場合は事前にint()
で変換するか、仕様を見直しましょう。
i = int(1.0) # → 1
print(nums[i])
20
よく使うインデックス取得パターン
最初と最後の要素を取得(0と-1)
先頭は0
、末尾は-1
が即答です。
長さに依存せずシンプルに書けます。
fruits = ["apple", "banana", "cherry", "date"]
first = fruits[0]
last = fruits[-1]
print(first, last)
apple date
任意の位置の要素を安全に取得
事前に範囲を検査するか、例外を補足するのが定石です。
用途に応じて使い分けます。
fruits = ["apple", "banana", "cherry", "date"]
# 1) 範囲チェック方式
i = 5
if 0 <= i < len(fruits):
print(fruits[i])
else:
print("(なし)") # フォールバック
# 2) 例外補足方式
try:
print(fruits[i])
except IndexError:
print("(なし)")
(なし)
(なし)
読みやすさ重視なら補助関数safe_get
の導入がおすすめです。
def safe_get(lst, i, default=None):
return lst[i] if -len(lst) <= i < len(lst) else default
print(safe_get(fruits, -2, "(なし)"))
cherry
複数の位置を取り出す(ループ+インデックス)
複数のインデックスをまとめて処理するときは、ループと安全取得の組み合わせが便利です。
fruits = ["apple", "banana", "cherry", "date"]
positions = [0, 2, -1, 5, -100] # 混在したインデックス
def safe_get(lst, i, default=None):
return lst[i] if -len(lst) <= i < len(lst) else default
for p in positions:
value = safe_get(fruits, p, default="(なし)")
print(f"{p:>4} → {value}")
0 → apple
2 → cherry
-1 → date
5 → (なし)
-100 → (なし)
また、全要素をインデックス付きで走査したい場合はenumerate()
が定番です。
for i, name in enumerate(fruits): # i: 0,1,2...
print(i, name)
0 apple
1 banana
2 cherry
3 date
ネストしたリストの要素取得(list[i][j])
2次元リストでの取得
2次元リスト(リストのリスト)は、行インデックス→列インデックスの順でアクセスします。
# 3x3の行列を例にする
matrix = [
[1, 2, 3], # 行0
[4, 5, 6], # 行1
[7, 8, 9], # 行2
]
print(matrix[1][2]) # 行1の列2 → 6
6
最初の[]
で外側のリスト、次の[]
で内側のリストに進むと理解すると混乱が減ります。
深いネストのアクセス順序
深くネストしていても、左から順に外側→内側へと段階的にアクセスします。
nested = [
[ ["a", "b"], ["c", "d"] ], # インデックス0
[ ["x"], ["y", "z"] ], # インデックス1
]
# 例: "c"を取り出す
print(nested[0][1][0]) # 外0 → 内1 → 最内0
# 例: "z"を取り出す
print(nested[1][1][1]) # 外1 → 内1 → 最内1
c
z
不規則な長さのネストでは途中のどこででもIndexError
が起き得るため、安全にたどる関数を用意すると実務で役立ちます。
from typing import Iterable, Any, Optional
nested = [
[ ["a", "b"], ["c", "d"] ], # インデックス0
[ ["x"], ["y", "z"] ], # インデックス1
]
def deep_get(lst: Any, indices: Iterable[int], default: Optional[Any] = None) -> Any:
"""複数インデックスで段階的に要素を取得。途中で失敗したらdefaultを返す。"""
cur = lst
try:
for i in indices:
cur = cur[i]
return cur
except (IndexError, TypeError):
# TypeError: curがリストでない(例えばint)のに[]でアクセスした場合
return default
print(deep_get(nested, [0, 1, 0])) # "c"
print(deep_get(nested, [1, 1, 1])) # "z"
print(deep_get(nested, [2, 0, 0], "?")) # 範囲外 → "?"
c
z
?
深い構造を扱うときこそ、安全なアクセスの重要性が高まります。
必要に応じてデータの整形や検証も併用すると堅牢です。
- 関連記事:リストの一部を取り出す – スライス
- 関連記事:Web APIの複雑なJSONを安全にパースする
まとめ
本記事では、リストのインデックス指定list[i]
の基礎から、安全な取得とエラー回避、よく使うパターン、ネストしたリストの扱いまでを段階的に解説しました。
要点は次の通りです。
リストは0始まりで、負のインデックスで末尾から参照できます。
範囲外はIndexError
、整数以外はTypeError
となるため、len()
による範囲チェックやtry/except
での保護が有効です。
ネストしたリストは外側から内側へ順に[]
を重ねてアクセスします。
インデックスの基本を確実に身につけることで、他の操作(スライスやソート、検索など)の理解にもつながります。