Python: 如何在“while”循环内嵌套 “if” 语句?

3

我是Python的新手,所以在一个其他人可能觉得简单的问题上遇到了麻烦。

这个问题的背景是欧拉计划中的第二个问题。该问题实际上要求我们将斐波那契数列中所有不超过4,000,000的偶数项相加。与其它许多在线解决方案不同,我决定通过从闭式公式计算第n个斐波那契项来解决这个问题。暂时假设此函数称为Fibonacci(n)

我的目标是循环遍历未知数量的整数,这些整数表示斐波那契集合的索引(即1、2、3、4等),并将每个值插入Fibonacci(n)。如果结果除以2没有余数,则将该斐波那契数添加到最初设置为0的某些值中。

以下是我目前的代码:

def Fibonacci(n): 
    return (1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n))

i=0
FibSum = 0
nFib = 0

while (nFib <= 10):

    nFib = Fibonacci(i)

    if(nFib%2==0):
        FibSum += nFib

    i += 1

print FibSum

是的,正如您所看到的,我将斐波那契数列限制在10而不是4,000,000;这仅用于测试。

现在,我的问题是:当我运行此代码时,我得到2.0而不是10.0(2和8是应该加在一起的两个斐波那契数)。

为什么?我猜想是因为循环在达到第三个斐波那契数(2)后停止,而没有继续进行。有人发现我的代码有什么问题吗?

如果您有任何进一步的问题,请评论。提前致谢。


1
只是一条与风格完全无关的注释,但是在 whileif 语句中不需要括号来包含条件。例如 while nFib <= 10: 就可以了。 - Some programmer dude
1
因为你使用了浮点数运算,所以得到的是 ~ 8.000000000000002 而不是 8。 - Ilja Everilä
1
问题在于浮点数。计算斐波那契数列涉及除法,这意味着使用浮点数。因此,模运算无法正确地进行评估。 - Ma0
1
在Python中,通常只有类名以大写字母开头。你应该将你的函数重命名为fibonacci。此外,由于花括号的不寻常使用和缺少空格,你的代码有点难以阅读。请阅读PEP 8 - user5547025
1
@LutzHorn:有道理,同意。谢谢分享! - Swadhikar
显示剩余5条评论
3个回答

3
Gal Dreiman提供的解决方案不错,但在函数内进行转换更好,以下是您修改后的代码:
def Fibonacci(n):
    return int((1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n)))

1
从数学角度来看,我更喜欢你的解决方案,因为斐波那契数列是一个整数序列,我认为浮点问题是计算问题导致的。因此,函数返回纸上方程式应该有的整数结果是合适的。谢谢! - daOnlyBG

2

您有一个浮点数问题(可以在此处阅读)- 返回的值“nFib”既不是整数也不是取整后的值。我运行了您的代码并在每次迭代中添加了对该值的打印,结果如下:

0.0
1.0
1.0
2.0
3.0000000000000004
5.000000000000001
8.000000000000002
13.000000000000002

解决方案是修改您的代码如下:

nFib = int(Fibonacci(i))

之后,我得到了输出结果:10。

感谢您的回复和链接! - daOnlyBG

2
问题出在 nFib%2==0 的比较上。你试图将浮点型的左值与整数0进行比较。因此,要么按照下面的方式修改if循环,要么修改返回值为return int((1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n)))
>>> def Fibonacci(n):
...     return (1/(5**0.5))*((((1+5**0.5)/2)**n)-(((1-5**0.5)/2)**n))
...
>>> i=0
>>> FibSum = 0
>>> nFib = 0
>>> while (nFib <= 10):
...     nFib = Fibonacci(i)
...     if(int(nFib%2)==0):
...             FibSum += nFib
...     i += 1
...
>>> print FibSum
10.0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接