dogdog
@dogdog

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

基礎知識のリストの参照でつまづいた。

解決したいこと

以下のコードの違いがわからず、何故エラーが起きるのかわかりません。

例)
漸化式をPythonで書きました。
リストaを40個用意しました。
a[1]=1 ,a[2]=1
a[i] = a[i-2]+a[i-1]のように求めます。

test.pyのコードは41個の要素があるリストを用意してあります。 
test_1.pyのコードは40個の要素があるリストを用意してあります。 

実行すると、test_1.pyだけが[list assignment index out of range]とエラーを吐き出します。

range(3,40)は3から39までを参照しますよね?
a[40]を求めるにしても、a[39]とa[38]を使うので、要素は41個もいらないと思うのですが、何故このようなエラーが起きるのでしょうか?
どなたか分かる方教えていただけますでしょうか。

発生している問題・エラー

 a[i]=a[i-2]+a[i-1]
IndexError: list assignment index out of range
test.py
a =[1]*41
for i in range(3,41):
    a[i]=a[i-2]+a[i-1]

print(a)
test_1.py
a =[1]*40
for i in range(3,41):
    a[i]=a[i-2]+a[i-1]

print(a)

自己解決できました。

基本リストはa[0]から始まる。そのためa[0]*40は、a[0]~a[39]のリストを用意する。

0

1Answer

range(3,40)は3から39までを参照しますよね?
a[40]を求めるにしても、a[39]とa[38]を使う

これは正しくて

要素は41個もいらないと思うのです

が怪しいです.a = [init]*nという書式で書いたnは,配列の要素数となる認識で間違いないのですが,Pythonのlistは0-indexedなので0からn - 1までのn個の要素にアクセスすることになります.これより外,つまりn番目の要素に対してアクセスするa[n]index out of rangeです.つまり,

a[40]を求めるにしても、a[39]とa[38]を使う

という操作のためには,aの配列長が41個なくては41-1つまりa[40]にアクセスできません.

40個の要素を求めたいのだから,41個も配列がいらないという認識は正しいのですが,配列の使い方がまるで1-indexedなため,41個必要としている.というのが現状です.

これを避けるためには,要素数を初めから40個で用意した上で,質問のコードでは一切使ってない0番目の要素を使うようなフィボナッチ数列を求めることを推奨します.

0-indexed Ver.
n = 40
a = [0] * n
a[1] = 1

for i in range(2, n):
    a[i] = a[i - 1] + a[i - 2]

print(a) # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887, 9227465, 14930352, 24157817, 39088169, 63245986]

フィボナッチ数列の一般項

F(n) = \frac{1}{\sqrt{5}}\left\{\left(\frac{1 + \sqrt{5}}{2}\right)^n - \left(\frac{1 - \sqrt{5}}{2}\right)^n\right\}

からもわかるように,$F(0)=0$,つまり配列aの0番目a[0]には0が入っているべきですね.質問のコードでは全ての要素を1で初期化してしまった上に,0番目について一切考慮されていないため,小難しくなっちゃった感じだとも思います.

0Like

Your answer might help someone💌