web-dev-qa-db-ja.com

Pythonのリスト内包表記を使用してフィボナッチ数列を作成するにはどうすればよいですか?

私はPythonを初めて使用しますが、Pythonのリスト内包表記機能を使用してフィボナッチ数列を生成できるかどうか疑問に思っていました。リスト内包表記がどのように実装されているのかわかりません。私は次のことを試みました(意図は最初の5つのフィボナッチ数を生成することでした):

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

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

7
PythonNewBie

そのようにすることはできません:リスト内包最初に評価されます、そしてそのリストは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)]

ここで注意してください結果をシリーズに追加しないでください。リスト内包表記は、.appendseriesで呼び出されます。ただし、エラーが発生しやすい副作用を伴うリスト内包表記を検討する人もいます。これは宣言型ではなく、注意深く行わないとバグが発生する傾向があります。

10

必要なシリーズの用語がいくつあるかがわかっている場合は、このようなリスト内包表記なしでコードをコンパクトに記述できます。

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)

アイテムの潜在的に無限のコレクションが必要な場合は、1つ以上のfunctionステートメントを含むyieldまたはジェネレーター式のいずれかを検討する必要があります。ジェネレータ式でフィボナッチ数を作成できるようにしたいと思いますが、どうやらできません。

5
Bill Bell

黄金比との関係を使用して、クリーンな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]
5
cdlane

Willem van Onsemが言ったことに基づいて構築するには:

フィボナッチ数列のn番目の項を計算する従来の方法は、ご存知のとおり、n-1項とn-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)
3
daphtdazz

リスト内包表記の使用:

n = int(input())
fibonacci_list = [0,1]
[fibonacci_list.append(fibonacci_list[k-1]+fibonacci_list[k-2]) for k in range(2,n)]

if n<=0:
   print('+ve numbers only')
Elif n == 1:
   fibonacci_list = [fibonacci_list[0]]
   print(fibonacci_list)
else:
   print(fibonacci_list)

多分それはこの問題の実行可能な解決策です...

0
nikhil_2017