def min_diff(arry_):
max_ =0
temp_ =0
for i in arry_:
nonlocal max_
nonlocal temp_
if i > max_:
nonlocal max_
nonlocal temp_
temp_ = max_
max_ =i
return max_-temp_
我想在循环外使用max_
和temp_
,但我得到一个错误
SyntaxError: no binding for nonlocal 'max_' found
nonlocal
只能应用于嵌套作用域的函数中。只有当你在另一个函数内部定义你的函数时,你才会得到一个嵌套的作用域。
Python没有块作用域;for
循环不创建新的作用域,因此不需要在循环中使用nonlocal
。变量在函数的其余部分都是可用的。直接删除nonlocal
语句:
def min_diff(arry_):
max_ = 0
temp_ = 0
for i in arry_:
if i > max_:
temp_ = max_
max_ = i
return max_ - temp_
在Python中,只有函数、类定义和推导式(list、set、dict推导式以及生成器表达式)有自己的作用域,只有函数可以作为闭包(非局部变量)的父作用域。
你的代码中还有一个bug;如果传入一个列表,其中第一个值也是列表中的最大值,则temp_
被设置为0
,然后永远不会更改。在这种情况下,您将永远找不到第二高的值,因为只有在第一个i
中,if i > max_:
才为真。在这种情况下,您还需要测试i
是否大于temp_
:
def min_diff(arry_):
max_ = 0
temp_ = 0
for i in arry_:
if i > max_:
temp_ = max_
max_ = i
elif i > temp_:
temp_ = i
return max_ - temp_
作为旁注:你不需要在你的局部变量中使用末尾下划线。在使用的所有本地名称中,只有max_
可能会掩盖内置的max()
函数,但由于您根本不使用该函数,因此实际上不需要在函数中使用max_
而不是max
。我个人会去掉函数中所有名称后面的_
下划线。我也会用不同的名字;可能是highest
和secondhighest
。
最后但并非最不重要的是,您可以使用heapq.nlargest()
函数来有效地获取这两个最大的值:
from heapq import nlargest
def min_diff(values):
highest, secondhighest = nlargest(2, values)
return highest - secondhighest
您可能需要在那里添加一些长度检查;如果len(values) < 2
是正确的,应该发生什么?