Trying to use variables outside of a for loop gives a SyntaxError: no binding for nonlocal 'max_' found

Trying to use variables outside of a for loop gives a SyntaxError: no binding for nonlocal 'max_' found

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

您的代码中也存在错误;如果您传入一个列表,其中第一个值也是列表中的最大值,则 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_ 而不是 [=26] =] 在你的函数中实际上不是必需的。我个人会删除函数中所有名称的所有尾部 _ 下划线。我也会使用不同的名字;也许 highestsecondhighest.

最后但同样重要的是,您可以使用 heapq.nlargest() function 高效地获得这两个最大值:

from heapq import nlargest

def min_diff(values):
    highest, secondhighest = nlargest(2, values)
    return highest - secondhighest

您可能想在那里添加一些长度检查;如果 len(values) < 2 为真,应该怎么办?