複数のfor文をまたぐ変数の使い方

Tweet


意外と以下の変数の使い方を思いつかない人が多いようなので解説します.

以下のプログラムがあるとします.for文が2つ続けて実行されるプログラムです.事情により,for文を2つに分けたままにする状況だとします.そして,最初のfor文で処理した結果に続けて,次のfor文の処理をしたいとします.

for文:
  配列Aの要素を1つ取り出す
  その要素に対して何らかの処理をする
for文:
  先程処理をした値に何らかの処理をする
  その結果を配列Bに格納する

この問題に対して,以下のように実装する人がいます.

import numpy as np
first=np.zeros(10)
final=np.zeros(10)
for i in range(10):
    a=first[i]
    a=a+i
    middle=a
for i in range(10):
    a=middle
    a=a*2
    final[i]=a
print(final)

この結果は以下のようになり,間違っています.

[18. 18. 18. 18. 18. 18. 18. 18. 18. 18.]

変数の中身が適切かどうか想像しなかったことが原因です.
ソースコードの処理内容を理解しなかったことが原因です.

では,解決のために解説していきます.分かりやすく例え話をします.変数は箱と例えることが出来ます.箱のような入れ物に数値を入れる,とイメージしてください.プログラミングの初期段階で説明される内容なので,プログラミングに取り組んでいる人にとってはわかりきっている例え話です.「その例え話は知ってるよ」と思うことでしょう.知っているなら,このような間違いはしないはずです.知っているくせにこのような間違いをしたのですか?あなたは箱に物を入れた経験がないのですか?

上の処理で,まず,0に0を足した値0を箱middleに入れましょう.

for文は繰り返し処理なので,次のループが実行されます.続いて,0に1を足した値1を箱middleに入れましょう.ここで,値は上書きされます.つまり,箱middleに入っていた0は消えて,箱middleには1が入ります.1つの箱には1つの値しか入れることが出来ません.1つの値を入れる分のサイズしかない箱です.

for文の最後では,箱middleに9が入ります.

次のfor文では,まず,箱middleから値を取り出します.よって,9を2倍にした値18が箱final[0]に入ります.

for文の次のループでは,9を2倍にした値18が箱final[1]に入ります.

for文の最後では,箱final[9]に18が入ります.

この問題を解決するためにはどうすればいいでしょうか?簡単ですよね.箱を10個用意すればいいだけです.その程度のことがなぜ分からなかったのですか?

正解のプログラムは以下の通りです.

import numpy as np
first=np.zeros(10)
middle=np.zeros(10)
final=np.zeros(10)
for i in range(10):
    a=first[i]
    a=a+i
    middle[i]=a
for i in range(10):
    a=middle[i]
    a=a*2
    final[i]=a
print(final)

正しい結果は以下の通りです.

[ 0. 2. 4. 6. 8. 10. 12. 14. 16. 18.]

最初のfor文の最初のループでは,0に0を足して箱middle[0]に入れます.次のループで,0に1を足して箱middle[1]に入れます.これを繰り返し,最後のループでは0に9を足して箱middle[9]に入れます.

次のfor文の最初のループでは,箱middle[0]から値を取りだし,2倍した0を箱final[0]に入れます.次のループで,箱middle[1]に入っている1を2倍した2を箱final[1]に入れます.これを繰り返し,最後のループでは9を2倍にした18を箱final[9]に入れます.

簡単ですよね.この程度のことは,ここまで丁寧に説明しなくても出来て欲しいものです.


もどる