Es ist ein Memo-Schreiben des Buches effektive Python von O'Reilly Japan. https://www.oreilly.co.jp/books/9784873117560/ P31~35
** Sortierbeispiel ** Sortieren Sie die Zahlen der Reihe nach, aber nehmen Sie an, Sie haben eine Zahl, die Sie priorisieren möchten
def sort_priority(values, group):
def helper(x):
if x in group:
return (0, x)
return (1, x)
values.sort(key=helper)
numbers = [8, 3, 1, 2, 5, 4, 7, 6]
group = {2, 3, 5, 7}
sort_priority(numbers, group)
print(numbers)
>>>
[2, 3, 5, 7, 1, 4, 6, 8]
Wenn Sie das Konzept der Schließung nicht kennen, können Sie sich kaum vorstellen, wie es funktioniert. Hier gibt es drei Punkte
** Bestimmen Sie, ob es in der Prioritätenliste enthalten ist oder nicht ** Basierend auf dem obigen Code möchte ich eine Implementierung implementieren, die True zurückgibt, wenn sie in der Prioritätsliste enthalten ist.
def sort_priority2(numbers, group):
found = False
def helper(x):
if x in group:
found = True #Es sollte hier wahr sein. .. ..
return(0, x)
return(1, x)
numbers.sort(key=helper)
return found
found = sort_priority2(numbers, group)
print('Found', found)
print(numbers)
>>>
Found False
[2, 3, 5, 7, 1, 4, 6, 8]
Ursprünglich sollte Found in der Berechnung True sein, aber aus irgendeinem Grund wird False zurückgegeben. Der Grund dafür ist der ** Umfang ** der Schließung.
Der obige Code gibt nicht False zurück, da der Bereich von Found außerhalb der Hilfsfunktion bleibt. Mit anderen Worten
def sort_priority2(numbers, group):
found = False #Weil gefunden im Umfang hier existiert. ..
def helper(x):
if x in group:
found = True #Gehen Sie hier nicht zum Bereich
return(0, x)
return(1, x)
numbers.sort(key=helper)
return found
Infolgedessen wird False zurückgegeben, das einen Bereich höher ist. Um dies zu vermeiden, bietet Python3 eine ** nichtlokale ** Funktion. Nicht lokal drückt das Zielfernrohr aus dem Verschluss
def sort_priority3(numbers, group):
found = False
def helper(x):
nonlocal found #Hier liegt der Umfang der gefundenen außerhalb der Hilfsfunktion
if x in group:
found =True
return(0, x)
return(1, x)
numbers.sort(key=helper)
return found
found = sort_priority3(numbers, group)
print('Found', found)
print(numbers)
>>>
Found True
[2, 3, 5, 7, 1, 4, 6, 8]
Dies ist die beabsichtigte Bewegung.
Wenn Sie jedoch nicht lokal in einer Großfunktion verwenden, wirkt sich dies auf den Bereich unbeabsichtigter Teile aus. Seien Sie also vorsichtig. Wenn Sie auf der sicheren Seite sein möchten, ist es besser, es in eine ähnliche Klasse zu verpacken, anstatt in die nichtlokale Funktion.
class Sorter(object):
def __init__(self, group):
self.group = group
self.found = False
def __call__(self, x):
if x in self.group:
self.found = True
return(0, x)
return(1, x)
sorter = Sorter(group)
numbers.sort(key=sorter)
assert sorter.found is True
>>>
(Keine Ausnahme wegen Behauptung)
Dieser kann verwendet werden, ohne sich um den Umfang zu kümmern.
Übrigens wird nonlocal in python2 nicht unterstützt.
Recommended Posts