見出し画像

【Python】SimplePrograms line 4 フィボナッチ数列を出力する

4行プログラムです。

コード

parents, babies = (1, 1)
while babies < 100:
    print ('This generation has {0} babies'.format(babies))
    parents, babies = (babies, parents + babies)

実行結果

This generation has 1 babies
This generation has 2 babies
This generation has 3 babies
This generation has 5 babies
This generation has 8 babies
This generation has 13 babies
This generation has 21 babies
This generation has 34 babies
This generation has 55 babies
This generation has 89 babies

解説

フィボナッチ数列です。
フィボナッチ数列というのは、1,2,から始まって、前の2つを足した数値が次の数になります。

1+2  1,2,
2+3  1,2,3,
3+5  1,2,3,5,
5+8  1,2,3,5,8,13

という風に、どんどん続いていきます。
今回は、この数列を生成するプログラムです。

ではまず、1行目。

parents, babies = (1, 1)

こんな風にまとめて設定できるんですねぇ。

C++ だと

int parents, babies = 1;

こんな風に書くことができました。
だけど、この書き方はあまり評判がよくなくて、実は「parents」は初期化できていない。でも、見た目は初期化しているように見えます。そこに間違いが潜みやすい。

その点、Python では次のような書き方ではエラー「TypeError: cannot unpack non-iterable int object」になるようです。

parents, babies = 1

きっちりと、変数の数分の初期値を書かないといけません。
C++ の問題点が改良されているような感じでしょうか。


次の行です。

while babies < 100:

次は「while」文。
babies」が 100 より小さい間はずっと繰り返す。
そういうプログラムです。
while」文の中で「babies」が更新されなければなりません。
でないとこの繰り返しから抜け出ることはできません。
いわゆる、無限ループになります。


次は「print」文。
また様変わりしていますね。

    print ('This generation has {0} babies'.format(babies))

文字列「' '」内の「{ }」は「置換フィールド」でした。
前回は「{name}」などのようにシンボルが書かれていましたが、
今度は「{0}」と数値です。
この「0」は何を意味するのでしょうか。

format」に並べる引数の順番のようです。
例えば、こんな風に書くと・・・

a, b, c, d, e = (10, 11, 12, 13, 14)
print('{2}, {1}, {4}, {0}, {3}, {2}'.format(a, b, c, d, e))

実行結果は次のようになります。

12, 11, 14, 10, 13, 12

{0}」は0番目の引数、
{1}」は1番目の引数、
{2}」は2番目の引数、・・・
ということのようです。

今回の場合、引数は「babies」だけですから、「{0}」は「babies」に置き換えられることになります。


そして最後の行なんですが。

    parents, babies = (babies, parents + babies)

これ・・・難しいですね。
これは、
「2行のコードを1行にまとめて書くことができます」
ということだけではありません。

次の2つのどちらの書き方とも違うものです。

    parents = babies
    babies = parents + babies
    babies = parents + babies
    parents = babies

例えば、
parents = 3
babies = 5

だとしましょう。

    parents = babies                # 5
    babies = parents + babies       # 10

最初に「parents」を「5」置き換えてしまった場合、
その次の「babies」の計算では新しい「parents=5」と計算してしまします。
本当は、計算するまえの「parents」である「3」と加算しないといけないのですが、そうはなりません。

    babies = parents + babies           # 8
    parents = babies                    # 8

逆に「babies」を先に計算してしまってもやはりダメです。
今度は「babies」は正しい値になりますが、
次の「parents」が新しい「babies」と同じになってしまいます。
こちらも本当は、計算するまえの「babies」である「5」でなければなりません。

    parents, babies = (babies, parents + babies)    # parents = 5  babies = 8

でもこの場合は違います。
parents」も「babies」も、今の「parents = 3」「babies = 5」をもとに決定します。
parents」を計算してから「babies」を計算するのでも、
babies」を計算してから「parents」を計算するのでもないのです。

ということは、こんな書き方ができるわけです。

a,b = (b,a)

a」と「b」をひっくり返すプログラムです。

a,b = (1,2)
が、たった一行で
a,b = (2,1)
に置き換わります。

これまでのプログラミング言語では、3行でないと書けないというのが多かったのではないでしょうか。

a_old = a
a = b
b = a_old

あるいは、こう書いた方がわかりやすいかもしれません。
でもそうすると、4行が必要になります。

a_old = a
b_old = b
a = b_old
b = a_old

それを

a,b = (b,a)

というたった一行で表現するとは、考えたものです。


間違いや改善方法、追加情報などありましたら、是非是非コメントくださいませ。


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