2017-02-21 42 views
2

我是新來的蟒蛇,我想知道如果我可以使用Python的列表理解功能生成斐波那契數列。我不知道列表解析是如何實現的。 我嘗試以下(意圖是生成的前五個斐波納契數):如何使用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

你不能做到這一點就像那樣,因爲*列表理解*在被添加到「系列」之前被評估爲拳頭...... –

+0

由於迭代X的輸入取決於迭代X的輸出,所以'reduce'是斐波那契數列的更好選擇-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)]

請注意,我們在這裏不會將結果添加到系列。列表理解僅用於在series上調用.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。我希望能夠使用生成器表達式來生成斐波那契數列,但顯然不能。

2

我們可以使用它的黃金比例關係,它寫成一個乾淨的Python列表理解(或發電機):

>>> 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]