Python 打印出斐波那契级数
我正在尝试编写一个简单的Python程序。它应该返回一个闭包,该闭包返回连续的斐波那契数:Python 打印出斐波那契级数,python,python-3.x,closures,fibonacci,Python,Python 3.x,Closures,Fibonacci,我正在尝试编写一个简单的Python程序。它应该返回一个闭包,该闭包返回连续的斐波那契数: def fibGen(): n_1 = 0 n_2 = 0 n = 1 def fib(): if n_1 ==0 and n_2 ==0: n_1 = 1 return n else: n = n_1 + n_2 n_2 = n_1
def fibGen():
n_1 = 0
n_2 = 0
n = 1
def fib():
if n_1 ==0 and n_2 ==0:
n_1 = 1
return n
else:
n = n_1 + n_2
n_2 = n_1
n_1 = n
return n
return fib
f = fibGen()
for i in range(0,10):
print(f())
我在运行时遇到此错误:
UnboundLocalError:赋值前引用的局部变量“n_1”
编辑:在我原来的帖子中,我没有把
n=1
包含在fibGen
的定义中,但实际上这是一个打字错误。无论如何,我仍然会得到相同的错误。您不能修改封闭变量,n_1,n_2在封闭空间中,而不是在函数空间中,这就是为什么您不能保存变量
使用非本地
关键字
def fibGen():
n_1 = 0
n_2 = 0
def fib():
nonlocal n_1, n_2
if n_1 ==0 and n_2 ==0:
n_1 = 1
return n_1 # return `n_1` here not `n`
else:
n = n_1 + n_2
n_2 = n_1
n_1 = n
return n
return fib
f = fibGen()
for i in range(0,10):
print(f())
Python根据绑定行为在编译时确定变量的范围。如果指定一个名称,或将其用作导入
目标(以及其他一些方法),则将该名称绑定到范围中
您正在绑定到fib()
函数中的n_1
和n_2
;这两个都被分配到了。这使得这两个名称在fib()
中成为本地名称,Python甚至不会查看周围的范围
您需要覆盖此行为,您可以使用:
nonlocal
明确地告诉编译器,您不希望它查看绑定行为,而是将名称视为闭包
接下来,在if
测试的第一个分支中使用n
,但在else
分支之外的任何地方都没有定义它。无论如何,您应该在那里返回1
:
def fibGen():
n_1 = 0
n_2 = 0
def fib():
nonlocal n_1, n_2
if n_1 ==0 and n_2 ==0:
n_1 = 1
return n_1
else:
n = n_1 + n_2
n_2 = n_1
n_1 = n
return n
return fib
最后但并非最不重要的一点是,您可以使用元组分配交换两个变量,无需中介:
def fibGen():
n_1 = 0
n_2 = 0
def fib():
nonlocal n_1, n_2
if n_1 ==0 and n_2 ==0:
n_1 = 1
else:
n_1, n_2 = n_1 + n_2, n_1
return n_1
return fib
我已经回顾了其中一些著名的算法,并想在Python中使用闭包分享我的斐波那契版本:
#!/usr/bin/env python
def fibonacci():
a = 0
b = 1
def internal_fibonacci():
nonlocal a, b
a, b = b, a+b
return a
return internal_fibonacci
def main():
f = fibonacci()
for i in range(0,10):
print("f(" + str(i) + ") => " + str(f()))
if __name__ == '__main__':
main()
比这里提供的其他解决方案要优雅一点。@Nearroyer66但我的答案很好地解释了代码中的问题。我知道,这就是为什么我“向上投票”取消了其他人的向下投票。有趣的是,这样的答案现在可以发布,而不必提及它是py3功能。也许我们终于超过了py2->py3的临界点。另外,+1,因为你看起来比被接受的答案提前了1分钟,但该答案使用了相同的函数、可用的名称和所有内容。有@PhilCooper的人谢谢。
#!/usr/bin/env python
def fibonacci():
a = 0
b = 1
def internal_fibonacci():
nonlocal a, b
a, b = b, a+b
return a
return internal_fibonacci
def main():
f = fibonacci()
for i in range(0,10):
print("f(" + str(i) + ") => " + str(f()))
if __name__ == '__main__':
main()