def get_fibonacci_sequence(max):
'''
Returns the Fibonacci sequence from the
first to the nth Fibonacci number.
'''
fib1 = 1
fib2 = 1
result = [fib1, fib2]
for i in range(2, max):
result.append(fib1 + fib2)
fib1 = fib2
fib2 = result[i]
return result
def get_nth_fibonacci(n):
'''Returns the nth Fibonacci number.'''
return get_fibonacci_sequence(n)[n - 1]
def main():
print("Would you like to have the sequence or the number?")
print("Enter 's' for sequence, and anything else for the number.")
seqOrNum = input("> ")
if seqOrNum == 's':
print("Up to which number would you like the sequence up to?")
max = int(input("> "))
print("The sequence up to the {}th Fibonacci number:".format(max))
print(get_fibonacci_sequence(max))
else:
print("Which Fibonacci number would you like to get?")
max = int(input("> "))
print("The {}th Fibonacci number is:".format(max),
get_nth_fibonacci(max))
if __name__ == "__main__":
main()
示例输出:
Would you like to have the sequence or the number?
Enter 's' for sequence, and anything else for the number.
> s
Up to which number would you like the sequence up to?
> 10
The sequence up to the 10th Fibonacci number:
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
关注点:
我的文档字符串使用得很好吗?
它是否遵循惯例?
#1 楼
生成器,而不是列表与其返回斐波纳契数的列表,不如返回一个斐波纳契数的列表,这将是非常有用的。也就是说,
yield
他们。这样,您甚至都不需要max:def get_fibonacci_numbers():
'''
Generator for all the fibonacci numbers
'''
fib1 = 1
fib2 = 1
yield fib1
yield fib2
while True:
yield fib1 + fib2
fib1 = fib2
fib2 = fib1 + fib2
注意,为清晰起见,实际上一次完成双重分配会更好:
def get_fibonacci_numbers():
'''
Generator for all the fibonacci numbers
'''
fib1, fib2 = 0, 1
while True:
yield fib2
fib1, fib2 = fib2, fib1 + fib2
如果需要第一个
n
数字,可以使用itertools.islice
。 为什么要生成器?
您可以轻松地将生成器转换为特定大小的列表,因此不会丢失任何功能。但是,使用轻量级生成器可以做的事太多了,而使用列表则无法做。考虑一些简单的问题-超过1000的第一个斐波那契数是什么?
>>> next(dropwhile(lambda x: x < 1000, get_fibonacci_numbers()))
欧拉问题2:找到400万以下的偶数斐波纳契数之和?
>>> sum(i for i in takewhile(lambda x: x < 4e6, get_fibonacci_numbers()) if i%2 == 0)
无法使用列表。至少,除非您不知道在哪里停车,否则不然。
如果只需要
n
,那就是:def get_nth_fibonacci(n):
return next(itertools.islice(
get_fibonacci_numbers(),
n, None))
#2 楼
绝对是docstring的很好用法,但最好将get_fibonnaci_sequence
docstring设为一行。简短的语言和一些简短的捷径使这变得容易:def get_fibonacci_sequence(max):
'''Return Fibonacci sequence from 1st-nth Fibonacci number.'''
您确实在很大程度上遵循了约定。好的名字和格式,但是我有一些注释。您可以在一行中分配
fib1 = fib2 = 1
,这更短,但也更清晰。将两个最新值与整数存储值一起存储在序列中也很奇怪。如果您想节省访问列表的时间,请坚持使用并更新
fib1
和fib2
,然后再将值添加到列表中。for i in range(2, max):
fib2 = fib1 + fib2
fib1 = fib2
result.append(fib2)
return result
您可以进行两种分配但是在一行中,由于Python具有智能的多重分配:
fib1, fib2 = fib2, fib1 + fib2
在执行任何分配之前,对右侧进行了全面评估,因此这可以满足您的需求,因为结果如下:
# fib1 = 1, fib2 = 2
fib1, fib2 = fib2, fib1 + fib2
fib1, fib2 = 2, 1 + 2
fib1, fib2 = 2, 3
现在评估完成,可以分配两个值。
您可以使用以下格式更好地格式化序列:
'\n'.join(get_fibonacci_sequence(max))
将它们放在新行上,或者', '
如果您希望每个值之间使用逗号。这些看起来比默认列表格式更好。那样,您应该避免使用
max
,因为它是Python中的内置函数,您可以对其进行阴影处理。相反,您通常可以使用max_value
。在这种情况下,num
或number
甚至都可以工作,我认为max
与您的实际意图有些偏差。