一覧PG-05-2 · 反復処理

breakとcontinue

負数を読み飛ばし、0を終了記号とする入力列を処理します。breakとcontinueの違いを確認した後、更新行へ進めない状態を回数制限付きで調べて修正します。

説明

breakはループを終了し、continueはその回の残りだけを飛ばします。whileで更新行をcontinueの後に置くと、同じ状態のまま繰り返す原因になります。

負数を読み飛ばし、0を終了記号とする入力列を処理します。breakとcontinueの違いを確認した後、更新行へ進めない状態を回数制限付きで調べて修正します。

1入力列と処理規則

2、-1、4、0、6を処理します。負数は無視、0で終了、その前の正数だけを加算します。

values = [2, -1, 4, 0, 6]負数と終了記号を含む列; total = 0合計初期値; print(values)処理対象

期待する合計は2+4の6です。-1を無視しても後の4へ進みますが、終了記号0の後の6へは進みません。

2読み飛ばしと打切り

各要素へ到達したときvisit、加算したときaddを表示します。

for value in values:各値を取得 print("visit", value)到達した要素 if value < 0: continue負数なら残りを飛ばす if value == 0: break0ならループ終了 total += value正数だけを加算 print("add", total)加算後の合計

-1にはvisitだけが出て次へ進み、0で反復全体が終わります。後ろの6にはvisitも出ません。continueとbreakが飛ばす範囲は異なります。

3終了記号もcontinueにした場合

0も単なる読み飛ばしに変えた処理を定義します。

def skip_nonpositive(data):別の処理規則 total = 0 for value in data: if value <= 0: continue0も単なる読み飛ばし total += value後ろの正数も対象 return total合計を返す

この処理は0以降の正数も加算します。終了記号という仕様を、0を加算しないという仕様へ置き換えたことになります。

4同じ入力で合計を比較

先ほどのbreakを使った合計と、新しい処理の戻り値を表示します。

print(total, skip_nonpositive(values))同じ入力の二つの処理結果

6と12です。どちらもエラーなく動きますが、0を終了記号とする条件を満たすのは前者です。例外が出ないことと、仕様どおりに終了することは別に確認します。

5更新へ進めない状態を調べる

whileで負数ならcontinueし、その後にi+=1があるコードを想定します。危険なループをそのまま回さず、一回分の状態更新を4回だけ追います。

i = 0先頭の添字; print("start", i)開始状態

i=0から始めます。以下のforは診断用の回数制限です。本来のwhileの終了条件i<len(values)だけでは止まれない状況を観察します。

6同じ負数から抜けられない

負数で更新が飛ばされる一回分の処理を反復します。

for attempt in range(4):診断を4回に制限 value = values[i]現在位置の値 print(attempt, i, value)状態の変化を記録 if value < 0: continue更新行を飛ばしてしまう条件 i += 1負数のとき到達しない更新

一回目だけiが0→1へ進み、残りはi=1・value=-1を繰り返します。continueが更新行を飛ばすためです。ここでは診断用forの4回制限で終了しています。

7次へ進む更新を先に行う

値を取り出した直後にiを進めてから、continueとbreakを判定する関数へ直します。

def scan(data): i = 0 total = 0 while i < len(data):範囲内だけ反復 value = data[i] i += 1取得後すぐ次の位置へ if value < 0: continue負数を読み飛ばす if value == 0: break終了記号で打切り total += value return total, i合計と次の位置

負数でも添字が進むようになりました。0を取り出した時点でもiは次の位置へ進んでいるので、返すiは「次に読む位置」です。値の役割を決めておくと、終了後の添字も解釈できます。

8修正後の終了位置

同じ入力を処理し、終了位置より後の値も表示します。

result, next_index = scan(values)修正した反復を実行; print(result, next_index, values[next_index:])合計・終了位置・未処理部分

合計6、次の位置4、未処理の残り[6]です。終了記号0は添字3にあり、そこまで調べて打ち切ったことが分かります。

まとめ

continueは次の反復、breakはループの外へ進みます。

whileではどの経路でも必要な状態更新へ進めるかを確認します。

操作履歴と解説を振り返れます。

Python 3

1
values = [2, -1, 4, 0, 6]; total = 0; print(values)
[2, -1, 4, 0, 6]
2
for value in values: print("visit", value) if value < 0: continue if value == 0: break total += value print("add", total)
visit 2
add 2
visit -1
visit 4
add 6
visit 0
3
def skip_nonpositive(data): total = 0 for value in data: if value <= 0: continue total += value return total
4
print(total, skip_nonpositive(values))
6 12
5
i = 0; print("start", i)
start 0
6
for attempt in range(4): value = values[i] print(attempt, i, value) if value < 0: continue i += 1
0 0 2
1 1 -1
2 1 -1
3 1 -1
7
def scan(data): i = 0 total = 0 while i < len(data): value = data[i] i += 1 if value < 0: continue if value == 0: break total += value return total, i
8
result, next_index = scan(values); print(result, next_index, values[next_index:])
6 4 [6]

演習完了