Imagine that I want to sort a list of numbers but prioritize one group of numbers to come first. This pattern is useful when you’re rendering a user interface and want important messages or exceptional events to be displayed before everything else. We can do this the following way:
def sort_priority(numbers, group): found = False def helper(x): # necessary to refer outer `found` nonlocal found if x in group: found = True return (0, x) return (1, x) numbers.sort(key=helper) return found
Above workds because Python supports closures—that is, functions that refer to variables from the scope in which they were defined: The helper func is able to access group arg.
The use of nonlocal is necessary to modify a variable in the enclosing scope: var found in this case.
Tip
Avoid using nonlocal statements for anything beyond simple functions. Define a class that can be called like a func, i.e. by [[2 Zettels/using call for stateful hooks in python|using call for stateful hooks in python]]:
class Sorter: 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)print("Found:", sorter.found)