使用列表推导的斐波那契数列

时间:2018-09-04 03:42:22

标签: python python-3.x

我想写一个列表推导,将给出Fibonacci的数字,直到达到400万为止。我想将其添加到列表中,以理解并求和均匀间隔的项。

from math import sqrt
Phi = (1 + sqrt(5)) / 2
phi = (1 - sqrt(5)) / 2
series = [int((Phi**n - phi**n) / sqrt(5)) for n in range(1, 10)]
print(series)
[1, 1, 2, 3, 5, 8, 13, 21, 34]

这是一个有效的示例代码,我想使用列表理解来编写类似的代码。请帮忙。

a, b = 1, 1
total = 0
while a <= 4000000:
    if a % 2 == 0:
        total += a
    a, b = b, a+b 
print(total)

2 个答案:

答案 0 :(得分:3)

由于您不需要执行实际的 list ,因此具有列表理解功能会很浪费。最好提供一个功能来为您完成所有繁重的工作,例如:

def sumEvenFibsBelowOrEqualTo(n):
    a, b = 1, 1
    total = 0
    while a <= n:
        if a % 2 == 0:
            total += a
        a, b = b, a + b 
    return total

然后仅用print(sumEvenFibsBelowOrEqualTo(4000000))对其进行调用。

如果您真的想要做一个斐波那契数字的列表(也许您想对它进行不同的理解),则可以进行一些小的修改来做到这一点-返回一个列表,而不是偶数值的总和:

def listOfFibsBelowOrEqualTo(n):
    a, b = 1, 1
    mylist = []
    while a <= n:
        mylist.append(a)
        a, b = b, a + b
    return mylist

然后您可以使用以下列表推导对偶数求和:

print(sum([x for x in listOfFibsBelowOrEqualTo(4000000) if x % 2 == 0]))

考虑到斐波纳契数很快变得非常大(所以列表就不会那么大),这可能并不太糟糕,但是对于其他不这样做的序列(或(对于更大的限制),构造列表可能会不必要地消耗大量内存。


一个更好的方法可能是使用一个生成器,如果您想要一个列表,则始终可以从中构造一个。但是,如果您不需要需要列表,则仍然可以在列表推导中使用它:

def fibGen(limit):
    a, b = 1, 1
    while a <= limit:
        yield a
        a, b = b, a + b

mylist = list(fibGen(4000000))                          # a list
print(sum([x for x in fibGen(4000000) if x % 2 == 0]))  # sum evens, no list

答案 1 :(得分:1)

从本质上说,列表理解是一个并行的过程;在此过程中,输入可迭代的输入,将某些功能应用于每个元素,并创建输出列表。当应用此功能时,它将独立于其他元素应用于每个元素。因此,列表推导不适合您所提出的迭代算法。可以在您的封闭式公式中使用它:

sum([int((Phi**n - phi**n) / sqrt(5)) for n in range(1, 10) if int((Phi**n - phi**n) / sqrt(5))%2 == 0])

如果要使用迭代算法,则生成器更合适。