클로저를 이용한 예제

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]

위의 정렬 예제가 동작하는 이유

정렬 예제 2: 우선순위가 높은 아이템을 발견했는지 여부를 추가적으로 확인

def sort_priority2(numbers, group):
    found = False                 # 스코프: "sort_priority2"
    def helper(x):
        if x in group:
            found = True          # 스코프: "helper"
            return (0, x)
        return (1, x)
    numbers.sort(key=helper)
    return found

numbers = [8, 3, 1, 2, 5, 4, 7, 6]
group = {2, 3, 5, 7}
found = sort_priority2(numbers, group)
print("Found: ", found)
print(numbers)

>>>
Found: False
[2, 3, 5, 7, 1, 4, 6, 8]

파이썬 인터프리터의 스코프 탐색 순서

클로저에서 데이터를 얻어오기

def sort_priority2(numbers, group):
    found = False
    def helper(x):
        nonlocal found
        if x in group:
            found = True
            return (0, x)
        return (1, x)
    numbers.sort(key=helper)
    return found
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

파이썬2의 스코프

# 파이썬2
def sort_priority(numbers, group):
    found = [False]
    def helper(x):
        if x in group:
            found[0] = True
            return (0, x)
        return (1, x)
    numbers.sort(key=helper)
    return found[0]