Попытка использовать переменные вне цикла for дает SyntaxError: не найдено связывания для нелокального 'max_'

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 ответ

Решение

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_ вместо max в вашей функции на самом деле не является обязательным требованием. Я бы лично отбросил весь трейлинг _ подчеркивает от всех имен в функции. Я бы также использовал разные имена; возможно highest а также secondhighest,

И последнее, но не менее важное, вы можете просто использовать heapq.nlargest() Функция для получения этих двух самых больших значений, эффективно:

from heapq import nlargest

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

Вы можете добавить некоторые проверки длины там; если len(values) < 2 правда, что должно произойти вместо этого?

Другие вопросы по тегам