Python3メモ 「a, b = b, a+b」はどのような順番で計算させれるのか

今回の内容

「a, b = b, a+b」はどのような順番で計算させれるのか。

環境情報

windows10
Python 3.8.1

何故疑問に思ったのか

pythonの勉強をしようと思い、問題集を解いていた際にフィボナッチ数列に関する問題がありました。 自分で作ったコードだと、結果は期待通りのものができましたが、気持ち悪いくらい強引な書き方をしていました。

a = 1
b = 1
while a < 2 ** 6:
    print(a)
    print(b)    
    a += b
    b += a

そこで、すっきりとした書き方を知るために回答を確認したところ、以下のようなコードが記載されていました。

a=b=1
while a < 2 ** 6:
    print(a)
    a, b = b, a+b

すごいシンプルですね。。
恥ずかしながら、この時に初めて変数に同時に値を入れられることを知りました。 そして、いざ自分の書いたコードを修正しようと思った時に、動きがよくわからなったため調べてみようと思いました。

ちなみに、正解の実行結果は以下になります。

1
1
2
3
5
8
13
21
34
55

検証

最初は単純にばらして、以下のようにすればよいのではないかと考えていました。

a=b=1
while a < 2 ** 6:
    print(a)
    a = b
    b = a+b

実行結果は以下のようになりました。。

1
1
2
4
8
16
32

改めて考えてみると、修正したコードは以下とほぼ同じなので、当たり前の動きなのですがますますよくわからなくなりました。

a=1
print(a)
while a < 2 ** 6:
    print(a)
    a += a

デバックのため以下のコードを実行しました。

a=b=1
while a < 2 ** 6:
    print(a,b,a+b)
    a = b
    b = a+b

出力結果は以下になりました。

1 1 2
1 2 3
2 3 5
3 5 8
5 8 13
8 13 21
13 21 34
21 34 55
34 55 89
55 89 144

上記の出力結果(右端のa+b)をもとに考えると、どちらを先に計算するというよりかは、まったく同時に計算しているようですね。

結論

「a, b = b, a+b」は「a=b」、「b=a+b」のどちらも計算される前の値を使っているということがわかりました。 つまり、ばらしてコードを書く場合は、「a」を追加する前の「b」という値を維持する、ほかの変数を用意するのが手っ取り早いと思います。 修正したコードは、以下になります。

a=b=c=1
while a < 2 ** 6:
    print (a)
    b += a
    a = c
    c = b

出力結果

1
1
2
3
5
8
13
21
34
55

出来ました!!けど、かなり野暮ったいコードになりますね。。
動きは理解できたので、次回から使っていこうと思います!