2017-02-21 2 views
2

私はPythonの初心者です。そして、私がPythonのリスト理解機能を使ってfibonacciシリーズを生成できるかどうか疑問に思っていました。リストの理解がどのように実装されているのか分かりません。 Iは、以下の(意図は最初の5つのフィボナッチ数を生成することであった)を試みた:Pythonのリストの理解を使用してフィボナッチシリーズを作成するにはどうすればよいですか?

series=[] 
series.append(1) 
series.append(1) 
series += [series[k-1]+series[k-2] for k in range(2,5)] 

コードのこの部分は、エラーをスロー:IndexError: list index out of range

リストの解説を使用してそのようなシリーズを生成することさえ可能かどうか教えてください。

+0

あなたはそれを行うことはできませんそのようなものは* list comprehension *が 'series'に追加される前に評価されているので... –

+0

' reduce'はフィボナッチシリーズのより良い選択です。反復Xの入力は反復Xの出力に依存します-1 –

答えて

4

あなたはそのようにそれを行うことはできません。リスト内包は最初を評価され、そのリストがseriesに追加されます。だから、基本的にそれはあなたが書かれていたようなものだ:

series=[] 
series.append(1) 
series.append(1) 
temp =[series[k-1]+series[k-2] for k in range(2,5)] 
series+= temp
ただしインスタンスのように、 力の副作用への道として リストの内包を使用することによってこの問題を解決することができ

series=[] 
series.append(1) 
series.append(1) 
[series.append(series[k-1]+series[k-2]) for k in range(2,5)]

をここでははシリーズに結果を追加しないことに注意してください。リストの理解は、で.appendが呼び出されるようにのみ使用されます。しかし、一部の人は誤っているのではなく、副作用のあるリスト内包を考慮しています。それはあまり宣言的ではなく、慎重に行わなければバグを導入する傾向があります。

+0

理解しています。どうもありがとうございました! – PythonNewBie

1

構築するかについては、ウィレムバンOnsemは言った:

フィボナッチ数列のn番目の項を計算する従来の方法は、あなたが認識しているとして、n-1n-2用語を合計することです。リストの理解は、理解中に(単一のリストの作成を除いて)副作用のないリストを作成するように設計されています。シーケンスの計算中にシーケンスの最後の2項を格納することは副作用であるため、リストの理解度は単独のタスクには不適切です。

これを安全に処理する方法は、リストの理解に何があるのか​​を気にする必要がないように、リストの理解に渡すことができるクロージャジェネレータ(本質的にいくつかの関連するプライベート状態を持つジェネレータ)を作ることです格納される:

def fib_generator(n): 

    def fib_n_generator(): 
     last = 1 
     curr = 1 

     if n == 0: 
      return 

     yield last 
     if n == 1: 
      return 

     yield curr 
     if n == 2: 
      return 

     ii = 2 
     while ii < n: 
      next = curr + last 
      yield next 
      last = curr 
      curr = next 
      ii += 1 

    return fib_n_generator() 

fib = [xx for xx in fib_generator(10)] 
print(fib) 
2

このシリーズのいくつの用語が必要なのか分かっているなら、このようなリストの理解なしにコンパクトにコードを書くことができます。

def Fibonacci(n): 
    f0, f1 = 1, 1 
    for _ in range(n): 
     yield f0 
     f0, f1 = f1, f0+f1 

fibs = list(Fibonacci(10)) 
print (fibs) 

不特定多数の用語が必要な場合は、これを使用できます。これは非常によく似ています。

def Fibonacci(): 
    f0, f1 = 1, 1 
    while True: 
     yield f0 
     f0, f1 = f1, f0+f1 

fibs = [] 
for f in Fibonacci(): 
    fibs.append(f) 
    if f>100: 
     break 
print (fibs) 

あなたがアイテムの潜在的に無限の収集を必要とするときあなたはおそらく考慮しなければならないのいずれか一つ以上のyield文またはジェネレータ式とfunction。私は、ジェネレータ表現でフィボナッチ数を作ることができるのが大好きですが、明らかに不可能です。私たちは、それは黄金比との関係だ使用してクリーンなPythonのリスト内包(または発電機)としてそれを書くことができ

2

:として

>>> series = [int((((1 + 5**0.5)/2)**n - ((1 - 5**0.5)/2)**n)/5**0.5) for n in range(1, 21)] 
>>> series 
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765] 
>>> 

またはもう少しうまく:

>>> square_root_of_five = 5**0.5 
>>> Phi = (1 + square_root_of_five)/2 
>>> phi = (1 - square_root_of_five)/2 
>>> 
>>> series = [int((Phi**n - phi**n)/square_root_of_five) for n in range(1, 21)] 
>>> series 
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765] 
関連する問題