Il s'agit d'un mémo écrit du livre efficace python d'O'Reilly Japon. https://www.oreilly.co.jp/books/9784873117560/ P31~35
** Exemple de tri ** Triez les nombres dans l'ordre, mais supposons que vous ayez un nombre que vous souhaitez prioriser
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]
Si vous ne connaissez pas le concept de fermeture, il est difficile d'imaginer comment cela fonctionne. Il y a trois points ici
** Incorporer la détermination de son inclusion ou non dans la liste des priorités ** Sur la base du code ci-dessus, je souhaite implémenter une implémentation qui renvoie True lorsqu'elle est incluse dans la liste des priorités.
def sort_priority2(numbers, group):
found = False
def helper(x):
if x in group:
found = True #Cela devrait être vrai ici. .. ..
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]
À l'origine, Found devrait être True dans le calcul, mais pour une raison quelconque, il renvoie False. La raison en est la ** portée ** de la fermeture.
Le code ci-dessus ne renvoie pas False car la portée de Found reste en dehors de la fonction d'assistance. En d'autres termes
def sort_priority2(numbers, group):
found = False #Parce que found existe dans la portée ici. ..
def helper(x):
if x in group:
found = True #N'allez pas à la portée ici
return(0, x)
return(1, x)
numbers.sort(key=helper)
return found
Par conséquent, False qui est une portée supérieure est renvoyé. Pour éviter cela, python3 fournit une fonction ** non locale **. nonlocal pousse la portée hors de la fermeture
def sort_priority3(numbers, group):
found = False
def helper(x):
nonlocal found #Ici, la portée de found est hors de la fonction d'assistance
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]
C'est le mouvement prévu.
Cependant, si vous utilisez non local dans une fonction à grande échelle, cela affectera la plage des pièces non souhaitées, alors soyez prudent. Si vous voulez être sûr, il vaut mieux l'envelopper dans une classe similaire au lieu de la fonction non locale.
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
>>>
(Aucune exception en raison de l'affirmation)
Celui-ci peut être utilisé sans se soucier de la portée.
À propos, non local n'est pas pris en charge dans python2.
Recommended Posts