Python으로 데이터 곱집합(Cartesian Product) 쉽게 만들기 - 경우의 수 목록 작성에 활용 가능

Python으로 데이터 곱집합(Cartesian Product) 쉽게 만들기 - 경우의 수 목록 작성에 활용 가능

곱집합(Cartesian Product)를 아시나요? 생소한 분도 계실 것입니다. 수학의 한 분과인 집합론에 자주 등장하는 개념입니다. 한국어로는 곱집합, 데카르트곱이라고 풀어 쓰기도 합니다.

읽기 어렵고 번거로우시죠? 쉽게 설명드릴게요.

한 학급에 여학생 세 명, 남학생 두 명이 있다고 가정합시다. 여학생 이름은 각각 '설현', '초아', '아이린'이고 남학생 이름은 각각 '보검', '승호'라 합니다. 담임 선생님이 여학생과 남학생 한 명씩을 미화부장으로 정하려고 하는데 누구를 시킬지 고민하다 공정하게 제비뽑기를 하기로 했습니다. 제비뽑기는 내일 수업 마치기 5분 전에 간단히 하기로 했습니다. 종이 여러 장을 준비해서, 종이마다 여학생 한 명의 이름과 남학생 한 명의 이름을 적어 두었습니다. 물론 종이 제비에 쓴 것이 보이지 않게 잘 접어 두었지요.

자, 이때 담임 선생님은 총 몇 장의 종이 제비를 만들어야 할까요? 쉬운 질문이지요? 간단히 머리를 써 보면 답이 나옵니다. '설현'에 보검, '설현'에 '승호', '초아'에 '보검', ..., '아이린'에 '승호'. 6장이 필요하겠죠?

그런데 집합 개수와 각 집합의 크기가 커진다면 머리로 쉽게 그려지지 않지요? 필요한 종이 제비의 수를 계산하는 것은 어렵지 않습니다.(학창시절 수학시간에 배웠던 Permutation, Combination) 하지만 실제 그 목록을 만들어 보라고 누군가 시킨다면, 그건 보통 일이 아니지요.

다행히 엑셀(Excel) 같은 도구도 있고 하지만, Python을 쓰면 단 한 줄로 그 작업을 할 수 있습니다.

import itertools

girls = ['설현', '초아', '아이린']
boys = ['보검', '승호']

result = itertools.product(girls, boys)
result = list(result) # 다루기 쉬운 리스트 객체로 변환
print(result)
# 출력: [('설현', '보검'), ('설현', '승호'), ('초아', '보검'), ('초아', '승호'), ('아이린', '보검'), ('아이린', '승호')]

셋 이상의 집합에 대해서도 가능합니다. itertools.product(girls, boys, dogs)처럼 한다면 3-튜블로 구성된 리스트가 나오겠죠?

list(itertools.product(girls, boys))와 같이 하면 정말 한 줄짜리 코드군요. 어떤가요? 쓸만한가요?