아마 컴퓨터를 사용하는 가장 큰 이유 중의 하나는 컴퓨터가 우리를 대신에 노가다를 뛰어주기 때문이지 않을까 싶네요 :) Computer Science 분야에서 때로는 정해진 해가 있는 것이 아니고, 모든 경우를 다 찾아봐야만 Optimal solution을 찾을 수 있는 경우들이 있는데, 이럴 경우 Exhaustive search를 한다고 표현합니다.(막찾기?) 여러 활용 예제들이 존재하겠지만, 우선은 가장 눈에 보이는 문제를 풀어보죠. A라는 집합이 주어졌습니다. 이 때 모든 부분집합을 출력해 봅시다 :) 제가 생각하는 이 문제의 접근법은 각 원소별로 있을 때와 없을 때를 나눠서 생각하는 것입니다. 그러면 만약 [a, b, c]라는 집합이 있으면, 개의 부분집합이 생기겠죠? 이런 경우에 많이 쓰는 방법은 recursive함수를 이용하는 것입니다.

def printAllSubset(A):
    printAllSubsetHelper(A, 0)

def printAllSubsetHelper(A, index):
    if index == len(A):
        print A
        return
    printAllSubsetHelper(A[:], index + 1) #index번째 원소를 건드리 않고 다음으로 넘어가는 경우
    A.pop(index) #index번째의 원소를 제외하고
    printAllSubsetHelper(A[:], index) #다음 원소로 넘어가는 경우. 주의할 점은 앞서 뺀 원소가 아예 사라졌기 때문에 index를 증가시키면 안된다!

>>> printAllSubset(['a', 'b', 'c'])
['a', 'b', 'c']
['a', 'b']
['a', 'c']
['a']
['b', 'c']
['b']
['c']
[]

후.. 뭔가 간단해 보이는데 굉장히 머리아프고 헷갈리는 코드였네요. Recursive함수들은 Base case와 Tree 방식으로 가지를 쳐 나가는 생각이 굉장히 중요합니다! 처음에는 잘 익숙치 않으니 많은 연습과 디버깅을 필요로 합니다 :)