range() / enumerate() / zip()
| 対応: | Python 2(2000) |
|---|
ループ処理で使われるシーケンス生成・インデックス付与・複数リストの並列処理を行う組み込み関数です。
構文
# 連続した整数のシーケンスを生成する range(終了値) range(開始値, 終了値) range(開始値, 終了値, ステップ) # イテラブルの各要素にインデックスを付けて返す enumerate(イテラブル, start=0) # 複数のイテラブルを並列にまとめる zip(イテラブル1, イテラブル2, ...) # イテラブルを逆順に返す reversed(シーケンス)
関数一覧
| 関数 | 概要 |
|---|---|
| range(stop) / range(start, stop, step) | 指定した範囲の整数を生成するオブジェクトを返します。for文や list() と組み合わせて使います。 |
| enumerate(iterable, start=0) | イテラブルの各要素を(インデックス, 値)のタプルで返します。start でインデックスの開始値を変更できます。 |
| zip(*iterables) | 複数のイテラブルから同じ位置の要素をまとめたタプルを返します。最も短いイテラブルに合わせて終了します。 |
| reversed(seq) | シーケンス(リスト・タプル・文字列など)を逆順に返すイテレータを生成します。 |
サンプルコード
range_basic.py
for i in range(5):
print(i, end=" ")
print()
for i in range(2, 10, 2):
print(i, end=" ")
print()
for i in range(5, 0, -1):
print(i, end=" ")
print()
nums = list(range(1, 6))
print(nums)
実行すると次のように出力されます。
python3 range_basic.py 0 1 2 3 4 2 4 6 8 5 4 3 2 1 [1, 2, 3, 4, 5]
enumerate_example.py
pilots = ["碇シンジ", "綾波レイ", "惣流アスカ"]
for i, pilot in enumerate(pilots):
print(f"{i}: {pilot}")
print()
for i, pilot in enumerate(pilots, start=1):
print(f"第{i}位: {pilot}")
実行すると次のように出力されます。
python3 enumerate_example.py 0: 碇シンジ 1: 綾波レイ 2: 惣流アスカ 第1位: 碇シンジ 第2位: 綾波レイ 第3位: 惣流アスカ
zip_reversed_example.py
names = ["綾波レイ", "碇シンジ", "惣流アスカ"]
scores = [85, 92, 78]
for name, score in zip(names, scores):
print(f"{name}: {score}点")
print()
person = dict(zip(["name", "age", "org"], ["綾波レイ", 14, "NERV"]))
print(person)
print()
for item in reversed(names):
print(item, end=" ")
print()
実行すると次のように出力されます。
python3 zip_reversed_example.py
綾波レイ: 85点
碇シンジ: 92点
惣流アスカ: 78点
{'name': '綾波レイ', 'age': 14, 'org': 'NERV'}
惣流アスカ 碇シンジ 綾波レイ
よくあるミス
よくあるミス1: range() の終了値がループに含まれると思う
『range(5)』は0〜4を生成します。5は含まれません。1から5まで処理したい場合は『range(1, 6)』と書きます。
for i in range(5):
print(i)
次のように記述します。
for i in range(1, 6):
print(i)
よくあるミス2: zip() が長さの異なるリストを最後まで処理すると思う
『zip()』は最も短いイテラブルで終了します。長さが異なるリストを全て処理したい場合は『itertools.zip_longest()』を使えます。
names = ["碇シンジ", "綾波レイ", "惣流アスカ"]
scores = [85, 92]
for name, score in zip(names, scores):
print(f"{name}: {score}点")
次のように記述します。
from itertools import zip_longest
names = ["碇シンジ", "綾波レイ", "惣流アスカ"]
scores = [85, 92]
for name, score in zip_longest(names, scores, fillvalue=0):
print(f"{name}: {score}点")
概要
『range()』はメモリ消費を抑えた遅延評価のオブジェクトを返します。『range(1000000)』としても100万個の整数をメモリ上に一度に展開するわけではなく、必要なときに順次生成します。終了値は結果に含まれません(例:『range(5)』は0〜4で、5は含まれません)。
『enumerate()』はインデックスを手動で管理する必要をなくします。『for i in range(len(fruits)):』のような書き方より『for i, fruit in enumerate(fruits):』のほうがPythonらしい(Pythonic)書き方とされています。
『zip()』は最も短いイテラブルに合わせて終了します。長さが異なるイテラブルを扱う場合で、すべての要素を処理したい場合は『itertools.zip_longest()』を使えます。また、複数のリストを組み合わせてループするのにも使いますが、ソート処理では『sorted()』と組み合わせることも多いです。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。