高速なカウントとインデックス作成のための Python 範囲

Python range ビルトインは、start、stop、step で定義された不変の整数シーケンスを作成します。 すべての数値のリストを割り当てることなく、信頼性の高いカウンターまたはインデックス オフセットが必要な場合に使用します。 範囲が生成する整数を開始、停止、およびステップ制御する方法を強調しています。 range を使用するループ パターンについては、「Python for ループの例」(/ja/examples/python/python-for-loop-example) を参照してください。

歩数カウントの Python 範囲の例

出力:

ここに出力が表示されます...

出力:

pen: 10 mm
stapler: 30 mm

この例の仕組み

  1. range(0, len(items), 2) は、リスト インデックスを 2 のステップで歩きます。
  2. ストップ値は排他的であるため、len(items) に達することはありません。
  3. 各インデックスは項目を読み取り、インデックスに関連付けられた値 (10、30) を出力します。

Python 範囲でよくある落とし穴

間違い 1: ストップ値が含まれることを期待しています。

for n in range(1, 5):
    print(n)
for n in range(1, 6):
    print(n)

発生理由: range は停止値の前で停止するため、包含シーケンスには stop + 1 が必要です。

間違い 2: カウントダウン中にプラスのステップを使用します。

for n in range(5, 0, 1):
    print(n)
for n in range(5, 0, -1):
    print(n)

なぜそうなるのか: 前向きなステップは上向きにのみ進みます。カウントダウンするには、ステップが負であるか、範囲が空である必要があります。

間違い 3: 開始、停止、またはステップに整数以外を渡します。

for rate in range(0, 1, 0.1):
    print(rate)
for basis_points in range(0, 101, 5):
    rate = basis_points / 100
    print(rate)

発生理由: range 引数は整数 (または __index__ を実装) である必要があり、ステップをゼロにすることはできません。

Python range と list(range): どちらを使用するか

次の場合には range を使用してください…次の場合には list(range(...)) を使用してください…
反復処理または整数によるインデックス付けのみが必要です。後で数値を保存または変更する必要があります。
ループ中に一定のメモリが必要です。具体的なリストに対して O(n) メモリを支払っても大丈夫です。
予測可能な開始、停止、ステップ計算を備えたシーケンス オブジェクトが必要です。appendsort のようなリスト メソッドが必要です。

経験則: 反復とオフセットについては range に到達します。メモリ内のすべての値が本当に必要な場合にのみリストを実体化します。 インデックスと値のペアが必要な場合は、enumerate を使用してください。Python 列挙の例 を参照してください。

パフォーマンスに関する考慮事項

range はスタート、ストップ、ステップのみを保存するため、巨大なシーケンスであっても O(1) メモリを使用します。 n in range(...) のようなメンバーシップ チェックは整数に対して定数時間であるため、リストをスキャンするよりも高速です。 list(range(...)) を呼び出すと、すべての値を割り当てるために O(n) のメモリと時間を支払うことになるため、実際のリストが必要な場合にのみ呼び出してください。

Python 範囲のその他のパタ​​ーン

負のステップで再試行をカウントダウンします。

for remaining in range(3, 0, -1):
    print(f"Retrying in {remaining}s")

負のステップによりシーケンスは下方向に移動しますが、ストップ値は依然として排他的です。 これにより、追加の条件なしでカウントダウンが短く、予測可能になります。

リストを保存せずに営業時間を生成します。

for hour in range(9, 18):
    print(f"{hour}:00")

range(9, 18) は 9 から 17 を返します。これは、排他的な停止を伴う 9 から 5 のスケジュールに一致します。 これは、番号を事前に構築せずに固定スロットを生成するクリーンな方法です。

Python 範囲を使用する場合

  • データが整数シーケンスであるカウンター、オフセット、または固定ステップ ループに使用します。
  • 事前に構築されたリストではなく、メモリ効率の高いシーケンスが必要な場合に使用します。
  • 非整数ステップの場合は避けてください。整数にスケールするか、他の数値ツールを使用します。
  • 後で値を保存または変更する必要がない限り、list(range(...)) は避けてください。