【问题标题】:Trying to use variables outside of a for loop gives a SyntaxError: no binding for nonlocal 'max_' found尝试在 for 循环之外使用变量会出现 SyntaxError: no binding for nonlocal 'max_' found
【发布时间】:2017-03-21 18:54:25
【问题描述】:
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

【问题讨论】:

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


    【解决方案1】:

    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 解析以及生成器表达式)有自己的作用域,并且只有函数才能充当闭包(非局部变量)的父作用域。

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

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

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

    您可能想在此处添加一些长度检查;如果len(values) < 2 为真,那么应该发生什么?

    【讨论】:

    • 但是 temp 在删除 non local 之后不会在本地使用。所以我没有得到想要的结果
    • @ShailabSingh:您的代码中可能还有其他错误,但不需要nonlocal。你没有给我们minimal reproducible example,没有样本输入、预期输出和实际输出,我无能为力。
    • @ShailabSingh:大概你想找出两个最高数字之间的差异?
    • @ShailabSingh:对于[5, 10, 9, 16],该函数产生6,即两个最高数字16和10之间的差异。如果这不是你想要的,你必须解释( 在您的问题中)您希望该函数做什么。
    • @ShailabSingh:但是,关于为什么会出现语法错误的问题已经得到解答。
    猜你喜欢
    • 2018-10-28
    • 2020-04-05
    • 2018-09-28
    • 1970-01-01
    • 2019-08-16
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多