range()の範囲指定でループが1回分ずれる
range()の終端は指定した値を含みません。全要素を回すつもりでrange(len(...) - 1)のように書くと、最後の1つが抜け落ちます。
なぜエラーが出ないのか
出力: 10
(エラーなし)- Pythonは何も報告しません。文法として正しいためです
出力: 10- 実際の挙動 — 期待した結果と食い違っている箇所
見つけ方- エラーが出ないので、出力を目で確かめるしかありません。この種の誤りが最も発見が遅れます
このエラーが出る典型パターン
パターン1
1 nums = [1, 2, 3, 4, 5] 2 total = 0 3 for i in range(4 ): ^ 4 total += nums[i] 5 print(total)
出力: 10期待: 15 (エラーにはなりません)
range(4)は0から3までの4個しか作りません。5個の要素をすべて合計したい場合はrange(5)、あるいはrange(len(nums))にします。
直し方: 4 を 5 にします。
広告
広告スロット(未設定)
パターン2
1 count = 0 2 for i in range(1, 5 ): ^ 3 count += 1 4 print(count)
出力: 4期待: 5 (エラーにはなりません)
range(1, 5)は1,2,3,4の4個までです。5まで含めたい場合は終端を1つ増やしてrange(1, 6)にします。
直し方: 5 を 6 にします。
パターン3
1 days = ["Mon", "Tue", "Wed", "Thu", "Fri"] 2 for i in range(len(days) - 1): ^ 3 print(days[i])
出力: Mon
Tue
Wed
Thu期待: Mon〜Friの5行 (エラーにはなりません)
range(len(days) - 1)は最後の要素の1つ手前で止まります。全要素を回すにはrange(len(days))にします。
直し方: len(days) - 1 を len(days) にします。
よくある誤解
「要素数と同じ数値を書けば全部回る」と思いがちですが、range(n)はn回(0からn-1まで)繰り返すという定義です。境界の扱いを勘違いすると1回分ずれます。
まとめ
range()の範囲指定でループが1回分ずれるは中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。