为什么在尝试求和斐波那契数时没有答案

Why no answer when trying to sum even Fibonacci numbers

我定义了一个函数来计算斐波那契数,效果很好。

现在我正在尝试将所有 <= n 的偶数斐波那契数加起来也 <= 4000000 但我没有得到任何输出。

def fib_iterative(n):
    a, b = 0, 1
    for i in range(0, n):
        a, b = b, a + b
    return a

def sum_even_fibs(n):
    total = 0
    n = 0
    while fib_iterative(n) < 4000000:
        if fib_iterative(n) % 2 == 0:
            total += fib_iterative(n)
            n += 1
    return total

print(sum_even_fibs(10))
# 1,1,2,3,5,8,13,21,34,55. 
# 2 + 8 + 34 = 44

关于代码:

if fib_iterative(n) % 2 == 0:
    total += fib_iterative(n)
    n += 1

如果第 n 个斐波那契数是偶数,这只会增加 n。这意味着,一旦到达 1,它就会变成一个无限循环。如果你在 whileif 语句之间立即放置一个 print(n),你会看到这个 - 它会打印出 0 后跟大量的 1s(大概直到你感到无聊并强行停止)。

要修复它,您需要将 n += 1 调回一个缩进级别,以便它在任何情况下都会递增:

if fib_iterative(n) % 2 == 0:
    total += fib_iterative(n)
n += 1

您的代码不起作用,因为您直到 n 才执行它,直到 4000000

才执行

你可以结合你的两个函数来创建这个。

def sum_even_fibs(n):
    a, b = 0, 1
    t = 0
    for i in range(n):
        a, b = b, a + b
        if a % 2 == 0:
            t += a
    return t

print(sum_even_fibs(10)) #44

正如评论中有人指出的那样,每三个数字都是偶数,因此您可以将其压缩为

def sum_even_fibs(n):
    a, b = 0, 1
    t = 0
    for i in range(n // 3):
        a, b = a + 2 * b, 2 * a + 3 * b
        t += a
    return t

print(sum_even_fibs(10)) #44

对于您不想处理任何超过 4000000 的数字的特定情况,您可以添加此 if 语句

def sum_even_fibs(n):
    a, b = 0, 1
    t = 0
    for i in range(n // 3):
        a, b = a + 2 * b, 2 * a + 3 * b
        if a >= 4000000:
            print("the fibonacci numbers in this calculation exceed 4000000")
            return None
        t += a
    return t

假设您一直这样做到 n=5。您应该计算五个斐波那契数。相反,您正在计算所有斐波那契数直到当前数的三次!对于每个 n,您应该只调用一次 fib_iterative 并重复使用结果。您还丢弃了 n 参数的值。

def sum_even_fibs(n):
    total = 0
    for x in range(n):
        current = fib_iterative(x)
        if current > 4000000:
            break
        if not current % 2:
            total += current
    return total

这仍然是低效的,因为您每次调用 fib_iterative(n) 时都会重新计算 n-1 的值。相反,基于生成器的解决方案将允许您只计算每个值一次。

from itertools import takewhile

def fib(n):
    x = 0
    y = 1
    for _ in range(n):
        yield x
        x, y = y, x+y

def sum_even_fibs(n):
    fibs = fib(n)
    evens = (x for x in fibs if not x%2)
    less_than_4000000 = takewhile(lambda x: x < 4000000, evens)
    return sum(less_than_4000000)