尝试在for循环之外使用变量会产生一个SyntaxError:对于非本地' max _'发现

时间:2016-11-08 08:13:55

标签: python python-3.x scope python-nonlocal

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

1 个答案:

答案 0 :(得分:3)

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中,只有函数,类定义和理解(列表,集合和字典理解以及生成器表达式)都有自己的作用域,只有函数可以作为闭包的父作用域(非局部变量)。

您的代码中也存在错误;如果您传入列表,其中第一个值也是列表中的最大值,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_代替{{1}在你的函数中实际上并不是一个要求。我个人会删除函数中所有名称的所有尾随max下划线。我也会用不同的名字;也许是_highest

最后但并非最不重要的是,您可以使用heapq.nlargest() function有效地获取这两个最大值:

secondhighest

你可能想在那里添加一些长度检查;如果from heapq import nlargest def min_diff(values): highest, secondhighest = nlargest(2, values) return highest - secondhighest 为真,那会发生什么呢?