Python備忘録3 -無限ループって怖いよな(ループ処理)-

今日はループ処理をサクッとおさらいする日。関係あるようでないけど、ループものって、なんか良いよな。

同じ処理を繰り返したい

同じ処理を毎回書くのは面倒臭いから、ループ処理を使おう。ループ処理には2種類ある。指定した回数だけ繰り返す方法と、条件を満たしている間だけ繰り返す方法だ。

指定した回数だけ繰り返す(for文)

指定した回数だけ繰り返す場合、for文を使う。

for  (変数)  in  (繰り返す範囲):
        処理の内容

繰り返す範囲を指定する方法は色々ある。今回は取り敢えず、シンプルに数字で指定してみる。range(x) で、0 から x 個の数値を取得できる。(単に x 回繰り返す意味でも使える。)

例えば、1月から12月までカウントしてみる。

for i in range(12):
    month = i + 1  #始まりが 0 なので 1 足す
    print(str(month) + "月", end=" ")

実行!

1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月 


if文と組み合わせることもできる。試しに、3の倍数と3のつく数字の時だけ、大声になってしまう人を表現してみよう。

for i in range(30):
    num = i + 1
    if num % 3 == 0 or "3" in str(num):
        print(str(num) + "!!!", end=" ")
    else:
        print(num, end="、 ")
        
    if num % 10 == 0:  #10ごとに改行
        print("")

1、2、さぁ↑ん!!

1、 2、 3!!! 4、 5、 6!!! 7、 8、 9!!! 10、 
11、 12!!! 13!!! 14、 15!!! 16、 17、 18!!! 19、 20、 
21!!! 22、 23!!! 24!!! 25、 26、 27!!! 28、 29、 30!!! 


***


ちなみに、range()にはオプションがあって、始まりの数字と、繰り返す間隔を指定することができる。

range(開始値, 停止値, 間隔)

開始値と間隔はデフォルトではそれぞれ、0 と 1 で、省略することができる。つまり、range(x) は省略せずに書くと range(0, x, 1) となる。停止値から後の値は、処理に含まれない(停止値の一つ前までが処理の範囲内)ので注意。

print("20までの整数で、5の倍数だけ表示")
for i in range(5, 21, 5):
    print(i, end=" ")

print("\n")  #改行

print("10から0までカウントダウン")
for j in range(10, -1, -1):  #間隔 -1 で逆順
    print(j, end=" ")

何はともあれ、色々試していれば解ってくる。

20までの整数で、5の倍数だけ表示
5 10 15 20 

10から0までカウントダウン
10 9 8 7 6 5 4 3 2 1 0 


条件を満たしている間だけ繰り返す(while文)

条件を満たしている間だけ繰り返す場合、while文を使う。条件の指定をミスると、無限にループしてしまうのが、怖いところ。

while  (条件):
        処理の内容



ここで、ちょっと脱線するけど、文字列の中に数字を組み込むときに便利な書き方がある。

”文字列{} 文字列{}”.format(値1, 値2)

こんな書き方をすると、{}の中に値1、値2を順に組み込むことができる。値は文字列でも、数値でもいい。例えば、12月25日をformat()で書くなら、
day = "{}月{}日".format(12, 25)
となる。



話を戻そう。
while文を使って、本日、これを書いてる12日から、クリスマスの25日まで、カウントダウンしてみたい。format()も使ってみよう。

day = 12

while day<25:
    print("今日は{}月{}日。 クリスマスまで、あと{}日".format(12, day, 25-day))
    day += 1
    
print("12月25日。 Merry Christmas!!")

もう、いくつ寝ると、クリスマス。

今日は1212日。 クリスマスまで、あと13日
今日は1213日。 クリスマスまで、あと12日
今日は1214日。 クリスマスまで、あと11日
今日は1215日。 クリスマスまで、あと10日
今日は1216日。 クリスマスまで、あと9日
今日は1217日。 クリスマスまで、あと8日
今日は1218日。 クリスマスまで、あと7日
今日は1219日。 クリスマスまで、あと6日
今日は1220日。 クリスマスまで、あと5日
今日は1221日。 クリスマスまで、あと4日
今日は1222日。 クリスマスまで、あと3日
今日は1223日。 クリスマスまで、あと2日
今日は1224日。 クリスマスまで、あと11225日。 Merry Christmas!!


ループの流れを変えたい

ループの途中でも、ある条件を満たした場合に限って、ループの流れを変えられる、そんな仕組みを作りたい。

ループから抜け出す(break文)

例えば、パスコード付きの扉があって、5回まで入力できるとする。当然、正しく入力できたら開くようにしたい。ここで break を使う。仮に、パスコードを「8308」とする。(横から見ると、なんか可愛いから。)

code = "8308"
num = input("パスコードを入力して下さい\n")

count = 0  #ミスした回数をカウント
for i in range(4):
    if num == code:
        print("どうぞ、お入り下さい。")
        break
    num = input("パスコードが違います。もう一度入力して下さい。\n")
    count += 1
    
if count == 4:
    print("さてはお前、偽物だな。")

5回とも、適当なコードを入力すると、、、

パスコードを入力して下さい
0000

パスコードが違います。もう一度入力して下さい。
0001

パスコードが違います。もう一度入力して下さい。
0002

パスコードが違います。もう一度入力して下さい。
0003

パスコードが違います。もう一度入力して下さい。
0004
さてはお前、偽物だな。

始めから、或いは途中で、正しいコードを入力すると、、、

パスコードを入力して下さい
8303

パスコードが違います。もう一度入力して下さい。
8308
どうぞ、お入り下さい。

正解した時点で扉が開いて、forループから抜け出せる。


特定の回だけ、スキップする(continue文)

指定した条件を満たした時に、continueより後の処理をスキップして、次のループを始める、というもの。

試しに、泉の女神様の話を表現してみたい。

ある日、木こりが泉に斧を落としてしまい、あたふたしていると、泉から美しい女神様が現れた。女神様は、木こりに質問を投げかけた。
「あなたが落としたのは、銀の斧ですか?それとも金の斧ですか?」

女神様は優しいので、2回までは嘘を見逃し、始めから質問してくれる。そういうことにしよう。

fool = 0  #嘘をついた回数をカウント

while fool < 3:
    ans = input("あなたが落としたのは、こちらの銀の斧ですか?[yes/no]\n")
    if ans == "yes":
        fool += 1
        print("もう一度聞きますよ?正直に答えてください。")
        continue
    
    ans = input("では、こちらの金の斧ですか?[yes/no]\n")
    if ans == "yes":
        fool += 1
        print("もう一度聞きますよ?正直に答えてください。")
        continue
    
    if fool == 0:
        print("""\nあなたは、一度も嘘をつきませんでしたね。
あなたが落とした斧も、金と銀の斧も、全て差し上げましょう。""")
        break
    else:
        print("""\nあなたは{}回、欲望に負けて嘘をつきましたね。
あなたが落とした斧だけ、お返しします。""".format(fool))
        break
    
if fool == 3:
    print("""\n3度もチャンスを与えたというのに、あなたは大嘘つきですね。
あなたの落とした斧は、お返しできません。さようなら。""")

“““で文字列を括ると、改行を含む文章を表現できる。

あなたが落としたのは、こちらの銀の斧ですか?[yes/no]
no

では、こちらの金の斧ですか?[yes/no]
no

あなたは、一度も嘘をつきませんでしたね。
あなたが落とした斧も、金と銀の斧も、全て差し上げましょう。

質問に正直に答え続けると、普通に物語が進み、break文でループから抜ける。今度は1回だけ、嘘をついてみる。

あなたが落としたのは、こちらの銀の斧ですか?[yes/no]
no

では、こちらの金の斧ですか?[yes/no]
yes
もう一度聞きますよ?正直に答えてください。

あなたが落としたのは、こちらの銀の斧ですか?[yes/no]
no

では、こちらの金の斧ですか?[yes/no]
no

あなたは1回、欲望に負けて嘘をつきましたね。
あなたが落とした斧だけ、お返しします。

金の斧か、と聞かれて「yes」と答えると、continue文でループの始まり、銀の斧の質問に戻る。「if fool == 0:」以降のコードはスキップされる。


終わり

今日は、ループ処理をサクッとやるつもりだったけど、思いの外、長くなってしまった。

関係あるようでないけど、ループものって、なんか良いよな。


この記事が気に入ったらサポートをしてみませんか?