1
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_andを使用したいのですが、エラーが発生しますtemp_

SyntaxError: no binding for nonlocal 'max_' found
4

1 に答える 1

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ません。その場合、2 番目に高い値を見つけることはできません。これは、最初の値のみが true に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()関数を使用してこれら 2 つの最大値を効率的に取得できます。

from heapq import nlargest

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

そこに長さのチェックを追加したい場合があります。len(values) < 2真の場合、代わりに何が起こるべきですか?

于 2016-11-08T08:20:27.140 に答える