空飛ぶチンアナゴの統計解析日記

統計解析を嗜むチンアナゴのメモ帳です

本当に初心者が学んでほしいコードの話 〜その1 コントロールフロー基本編2〜

前回

の続きで、基本的なループ処理の話をしていきます。
ループの種類は大きく分けて

  • forループ
  • whileループ

の2種類があります。
今回はこの二つについて触れていきます。

そもそもループ処理のありがたみとはなにか?

同じようなコードを何度も何度も何度もコピペしたくない
これにつきます。
その3で触れる予定の「関数」でもそうなのですが、コピペの回数が増えれば触れるほどコードのミスが増えます。
例えば、1から10までの10個数字を画面に表示する際に

print(1)
print(2)
print(3)
print(4)
print(5)
print(6)
print(7)
print(8)
print(9)
print(10)

と書くこともできますが

for i in range(1, 11):
    print(i)

と書いたほうがコピペを繰り返して手入力で変更することによるエラーもなく、コードもすっきりと読みやすくなります。
この手の繰り返す処理を人間の手入力でなんとかしようとすると、経験上時間と労力の割にはエラーが多いような気がします。

forループ

「サイコロを3回転がしたい」のように処理の回数が決まっている時に役立つのがforループです。
基本的な構文は

for 適当な変数名 in 範囲を指定:
    処理

という形になります。
例えば6面体のサイコロを3回転がして、その合計を表示する場合、

import random

dice_sum = 0
for i in range(3):
   d6 = random.randint(1,6)
   print('サイコロの出目は', d6)
   dice_sum = dice_sum + d6

print('サイコロの出目の合計は', dice_sum)

とコードを入れて実行すると

サイコロの出目は 4
サイコロの出目は 1
サイコロの出目は 2
サイコロの出目の合計は 7

と画面に表示されるはずです*1
このコードの中では

  1. サイコロを振る
  2. サイコロの出目を表示する
  3. サイコロの出目をdice_sumに加算する

という処理をrangeの中の回数(この場合は3回)実行しています。
ループ処理を使わずに書くと

import random

dice_sum = 0

# 1回目のサイコロ
d6 = random.randint(1,6)
print('サイコロの出目は', d6)
dice_sum = dice_sum + d6

# 2回目のサイコロ
d6 = random.randint(1,6)
print('サイコロの出目は', d6)
dice_sum = dice_sum + d6

# 3回目のサイコロ
d6 = random.randint(1,6)
print('サイコロの出目は', d6)
dice_sum = dice_sum + d6

# 最終的な出目を表示
print('サイコロの出目の合計は', dice_sum)

と大変煩わしくなるので、同じ処理を規定の回数だけ繰り返すのであればforループを使うのが賢明です。

whileループ

whileループは「出口が決まってる」時に使います。
「出口が決まっている」とは例えば「サイコロを振った合計が10を越える時まで」というループを抜ける条件だけは決まっているけど、ループを抜けるのに何回同じ処理を繰り返すのかが決まっていない状態です。
サイコロの出目の合計が10を越えるために必要な回数を知りたいということであれば

import random

dice_times = 0
dice_sum =0 

while dice_sum<10:
   d6 = random.randint(1, 6)
   dice_sum = dice_sum + d6
   print('今回の出目は' + str(d6) + 'でした。出目の合計は' + str(dice_sum) + 'です')
   dice_times += 1

msg = 'サイコロの出目が10を越えるの必要な回数は' + str(dice_times) + '回でした'
print(msg)

とコードを入力し実行すると

今回の出目は4でした。出目の合計は4です
今回の出目は1でした。出目の合計は5です
今回の出目は3でした。出目の合計は8です
今回の出目は4でした。出目の合計は12です
サイコロの出目が10を越えるの必要な回数は4回でした

と表示されます*2
出目の合計が10を超えた4回目の処理でループを抜け出していることがわかります。
同じコードを何回も実行してみると分かりますが、何回目の処理でループから抜けるのかは毎回ランダムですが、出目の合計が10を超えたところでループを抜け出しています。
このようにwhileループはループを抜ける条件のみが決まっている時に使用しましょう。

今日のまとめ

forループ:「ある処理を規定の回数行いたい時」に使用する
whileループ:「ループを抜ける条件のみが決まっている時」に使用する

課題

6面体のサイコロの出目の合計が10を越える時に必要なサイコロを転がす回数の平均値を知りたいと仮定します。
この試行を100回行うと仮定した時、10を越える時に必要なサイコロを転がす回数の平均値は何回でしょうか?

少し難しい課題ですが是非トライしてみてください。

*1:数字はランダムなので必ずしも一致するとは限りません

*2:数字はランダムなので必ずしも一致するとは限りません