还有另一个线程来讨论Python中的Fibo系列。这是为了将代码调整为更加pythonic。 How to write the Fibonacci Sequence in Python
我爱上了我为解决Project Euler Q2而编写的这个程序。我在Python中进行新编码,每次使用Pythonic方式都会感到高兴!你能建议一个更好的Pythonic方法吗?
Project Euler Q2。找出Fibonacci序列中所有偶数项的总和,不超过四百万。
fib=[]
def fibo(a=-1,b=1,upto=4000000):
if a+b>=upto:
return
else:
a,b=b,a+b
fib.append(b)
fibo(a,b)
fibo()
even=[i for i in fib if not i%2]
print sum(even)
答案 0 :(得分:16)
使用generator是一种Pythonic方法,可以在保留内存的同时生成长序列:
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
import itertools
upto_4000000 = itertools.takewhile(lambda x: x <= 4000000, fibonacci())
print(sum(x for x in upto_4000000 if x % 2 == 0))
答案 1 :(得分:14)
首先我将fibo()作为生成器:
def fibo(a=-1,b=1,upto=4000000):
while a+b<upto:
a,b = b,a+b
yield b
然后我也选择将均匀度作为生成器而不是列表理解。
print sum(i for i in fibo() if not i%2)
答案 2 :(得分:4)
首先,我建议在计算它们时总结这些术语,而不是将它们存储在一个数组中,然后对数组进行求和,因为除了将它们添加起来之外,你不需要对各个术语做任何事情。 (这在任何语言中都是很好的计算意义)
答案 3 :(得分:2)
我会做出以下更改:
除此之外,它合理地 Pythonic。
def even_fib_sum(limit):
a,b,sum = 0,1,0
while a <= limit:
if a%2 == 0:
sum += a
a,b = b,a+b
return sum
print(even_fib_sum(4000000))
答案 4 :(得分:2)
我在@constantin' answer中使用斐波纳契生成器,但生成器表达式可以用普通的for
循环替换:
def fibonacci(a=0, b=1):
while True:
yield a
a, b = b, a + b
sum_ = 0
for f in fibonacci():
if f > 4000000:
break
if f % 2 == 0:
sum_ += f
print sum_
答案 5 :(得分:1)
这是另一种直接方法 它依赖于一些属性:
第4点可以从中看出:
Sum of first 3N fibonacci numbers
=(F(1) + F(2))+ F(3) +(F(4) + F(5))+ F(6) + ... +(F(3N-2) + F(3N-1))+ F(3N)
= F(3) + F(3) + F(6) + F(6) + ... + F(3N) + F(3N)
= 2( F(3) + F(6) + ... + F(3N) )
= 2 ( Sum of odd fibonacci numbers up to F(3N) )
因此转换我们的最大值4000000计算最高斐波那契数的索引 少于它。
int n = floor(log(4000000*sqrt(5))/log(phi)); // ( = 33)
33可被3整除,因此它是一个偶数斐波纳契数,如果不是,我们需要像这样调整n。
n = (n/3)*3;
如果由
给出,所有斐波纳契数的总和到此为止sum = floor( pow( phi, n+2 ) + 0.5 ) - 1; // ( = 9227464 )
所有偶数的总和是这个数字的一半:
sum_even = sum/2; // ( = 4613732 )
关于这一点的好处是它是一个O(1)(或O(log(N)),如果你包括pow / log成本算法,并且工作在双打..所以我们可以计算非常的总和很大的价值观。
注意:我编辑并从这个问题的封闭副本中移动了这个答案。 Fibonacci under 4 millions
答案 6 :(得分:0)
在Python 3中,至少如果你给sum
函数一个生成器,它会懒惰地评估它,所以不需要重新发明轮子。
这就是@Constantin所做的并且是正确的。
通过比较使用生成器的内存使用情况进行测试:
sum(range(9999999))
与不这样做相比:
sum(list(range(9999999)))
具有生成器的那个不会导致具有更高数字的内存异常。
答案 7 :(得分:0)
print ("Fibonacci Series\n")
a = input ("Enter a nth Term: ")
b = 0
x = 0
y = 1
print x,("\n"), y
while b <=a-2:
b = b+1
z = x + y
print z
x = y
y = z
答案 8 :(得分:0)
def main():
a = 1
b = 2
num = 2
while b < 4000000:
a, b = b, a+b
num += b if b % 2 == 0 else 0
print num
if __name__ == '__main__':
main()