#
7.3 `for` 文

`for` 文は、配列 (文字列、タプルまたはリスト) や、その他の 反復可能なオブジェクト (iterable object) 内の要素に渡って反復処理を 行うために使われます:

  `for_stmt` | ::= | `"for" target_list "in" expression_list ":" suite`
  |  | `["else" ":" suite]`

  Download entire grammar as text.

式リストは一度だけ値評価されます; 結果はイテレーション可能な オブジェクトにならなければなりません。`expression_list` の結果からイテレータが生成されます。 次に、配列の各要素についてインデクスの小さい順に一度だけスイートを 実行します。このとき配列内の要素が通常の代入規則を使ってターゲットリスト に代入され、その後スイートが実行されます。全ての要素を使い切ると (配列が空の場合にはすぐに)、 `else` 節があればそれが 実行され、ループを終了します。

最初のスイート内で `break` 文が実行されると、`else` 節の スイートを実行することなくループを終了します。 `continue` 文が最初のスイート内で実行されると、 スイート内にある残りの文の実行をスキップして、式の真偽評価に戻ります。

スイートの中では、ターゲットリスト内の変数に代入を行えます; この代入によって、次に代入される要素に影響を及ぼすことはありません。

ループが終了してもターゲットリストは削除されませんが、配列が 空の場合には、ループでの代入は全く行われません。 ヒント: 組み込み関数 `range()` は、 Pascal 言語における `for i := a to b do` の効果を エミュレートするのに適した数列を返します; すなわち、 `range(3)` はリスト `[0, 1, 2]` を返します。

警告: ループ中の配列の変更には微妙な問題があります (これは 変更可能な配列、すなわちリストで起こります)。 どの要素が次に使われるかを追跡するために、内部的なカウンタが 使われており、このカウンタは反復処理を行うごとに加算されます。 このカウンタが配列の長さに達すると、ループは終了します。 このことは、スイート中で配列から現在の (または以前の) 要素を 除去すると、(次の要素のインデクスは、すでに取り扱った要素の インデクスになるために) 次の要素が飛ばされることを意味します。 同様に、スイート中で配列中の現在の要素以前に要素を挿入すると、 ループ中で現在の要素が再度扱われることになります。 こうした仕様は、厄介なバグになります。配列全体に相当するスライスを 使って一時的なコピーを作ると、これを避けることができます。

    for x in a[:]:
        if x < 0: a.remove(x)