<청춘> 격정적으로 사는 것

밤을 새고 공부한 다음 날 새벽에 느꼈던 생생한 환희와 야생적인 즐거움을 잊을 수 없다

파이썬 Python

[파이썬 Python] itertools , 순열과 조합 (permutations, combinations)

수학도 2021. 5. 26. 20:01

itertools

itertools 는 파이썬에서 반복되는 데이터를 처리하는 기능을 제공하는 라이브러리이다.

대표적으로, permutations(순열), combinations(조합) 클래스가 포함되어 있다.

 

경우의 수

경우의 수란 한 번의 시행에서 '일어날 수 있는 사건의 가지 수'를 의미한다.

'동전 던지기' 시행에서 경우의 수는 {앞면, 뒷면} 이므로 2가지이다.

'주사위 던지기' 시행에서 경우의 수는 {1, 2, 3, 4, 5, 6} 이므로 6가지이다.

 

순열 (Permutations)

순열이란 서로 다른 n개에서 r개를 선택하여 일렬로 나열하는 것을 의미한다. (순서를 고려함)

기호로 쓰면 nPr 이고, 경우의 수를 계산하는 공식은 nPr = n!/(n-r)! 이다.

 

예) 반장, 부반장 뽑기

  • [짱구, 철수, 유리] 가 있을 때 [반장, 부반장]을 뽑는 순열은 [짱구, 철수], [짱구, 유리], [철수, 짱구], [철수, 유리], [유리, 짱구], [유리, 철수] 이고, 경우의 수는 3!/(3-2)! = 3*2*1/1 = 6 이다.
  • [짱구, 철수] 는 짱구가 반장, 철수가 부반장인 경우
  • [철수, 짱구] 는 철수가 반장, 짱구가 부반장인 경우
  • 따라서 순서가 다르면 경우가 다른 것이기 때문에 두 경우 다 세어준다.

 

예) n=3, r=2 일때

서로 다른 n개를 [1, 2, 3] 라고 하면 순열은 [1, 2], [1, 3], [2, 1], [2, 3], [3, 1], [3, 2] 이고 경우의 수는 3P2 = 3!/(3-2)! = 6 이다.

 

permutations( iterable객체, r ) 는 리스트와 같은 iterable(반복가능한) 객체에서 r개의 데이터를 뽑아 일렬로 나열하는 모든 경우(순열)를 계산해준다. permutations 는 클래스이므로 객체 초기화 이후에는 리스트 자료형으로 변환하여 사용한다.

from itertools import permutations

data = [1, 2, 3]

# permutations(data, 3) : data 리스트에서 3개를 뽑아 일렬로 나열하는 모든 순열을 계산
# 객체 초기화 (값을 담아줬으면) 이후에는 리스트 자료형으로 변환하여 사용
result = list(permutations(data, 3))

print(result)
# print 결과

[(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]

 

 

조합 (Combinations)

조합이란 서로 다른 n개에서 순서에 상관없이 서로 다른 r개를 선택하는 것을 의미한다.

기호로 쓰면 nCr 이고, 경우의 수를 계산하는 공식은 nCr = n!/r!*(n-r)! 이다.

 

예) 주번 2명 뽑기

  • [짱구, 철수, 유리] 가 있을 때 [주번, 주번]을 뽑는 조합은 [짱구, 철수] , [짱구, 유리], [철수, 유리] 이고, 경우의 수는 3!/2!(3-2)! = 3*2*1 / 2*1*1 = 3 이다.
  • [짱구, 철수] 는 짱구도 주번, 철수도 주번인 경우
  • [철수, 짱구] 는 철수도 주번, 짱구도 주번인 경우
  • 순서에 상관없이 경우가 같은 것이기 때문에 둘 중 하나만 세어준다.

 

예) n=3, r=2 일때

서로 다른 n개를 [1, 2, 3] 라고 하면, 조합은 [1, 2], [1, 3], [2, 3] 이고, 경우의 수는 3C2 = 3!/2!(3-2)! = 3 이다.

 

combinations( iterable객체, r )  는 리스트와 같은 iterable(반복가능한) 객체에서 r개의 데이터를 뽑아 순서를 고려하지 않고 나열하는 모든 경우(조합)를 계산해준다. combinations 는 클래스이므로 객체 초기화 이후에는 리스트 자료형으로 변환하여 사용한다.

from itertools import combinations

data = [1, 2, 3]

# combinations(data, 3) : data 리스트에서 3개를 뽑아 순서를 고려하지 않고 나열하는 모든 조합을 계산
# 객체 초기화 (값을 담아줬으면) 이후에는 리스트 자료형으로 변환하여 사용
result = list(combinations(data, 3))

print(result)
# print 결과

[(1, 2, 3)]

 

중복순열 (Product)

원소를 중복한 경우의 수를 포함하는 순열을 계산한다.

product 객체를 초기화할 때는 뽑고자 하는 데이터의 수를 repeat 속성값으로 넣어준다.

product 는 클래스이므로 객체 초기화 이후에는 리스트 자료형으로 변환하여 사용한다.

from itertools import product

data = [1, 2, 3]

# product(data, 3) : data 리스트에서 3개를 뽑아 일렬로 나열하는 모든 순열을 계산(중복 허용)
# 객체 초기화 (값을 담아줬으면) 이후에는 리스트 자료형으로 변환하여 사용
result = list(product(data, repeat=3))

print(result)
# print 결과

[(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 2, 1), (1, 2, 2), (1, 2, 3), (1, 3, 1), (1, 3, 2), (1, 3, 3), 
(2, 1, 1), (2, 1, 2), (2, 1, 3), (2, 2, 1), (2, 2, 2), (2, 2, 3), (2, 3, 1), (2, 3, 2), (2, 3, 3), 
(3, 1, 1), (3, 1, 2), (3, 1, 3), (3, 2, 1), (3, 2, 2), (3, 2, 3), (3, 3, 1), (3, 3, 2), (3, 3, 3)]

 

중복조합 (Combinations_with_replacement)

원소를 중복한 경우의 수를 포함하는 조합을 계산한다.

Combinations_with_replacement 는 클래스이므로 객체 초기화 이후에는 리스트 자료형으로 변환하여 사용한다.

 

from itertools import combinations_with_replacement

data = [1, 2, 3]

# Combinations_with_replacement(data, 3) : data 리스트에서 3개를 뽑아 일렬로 나열하는 모든 조합을 계산(중복 허용)
# 객체 초기화 (값을 담아줬으면) 이후에는 리스트 자료형으로 변환하여 사용
result = list(combinations_with_replacement(data, 3))

print(result)
# print 결과

[(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 2, 2), (1, 2, 3), (1, 3, 3), 
(2, 2, 2), (2, 2, 3), (2, 3, 3), 
(3, 3, 3)]

 

math

math 라이브러리는 자주 사용되는 수학적인 기능을 제공하는 라이브러리이다.

math 에 있는 perm(순열) 과 comb(조합) 은 경우의 수를 계산한다.

 

perm(n, r) = nPr =  n!/(n-r)! 

comb(n, r) = nCr = n!/r!*(n-r)! 

 

from math import perm
from math import comb

data = [1, 2, 3]

# 경우의 수를 계산한다. nPr = n!/(n-r)!
result = perm(3, 3)
print(result)

# 경우의 수를 계산한다. nCr = n!/r!(n-r)!
result = comb(3, 3)
print(result)
# print 결과

6
1

 

 

 

 

출처

나동빈, 『이것이 취업을 위한 코딩테스트다 with 파이썬』, 한빛미디어(주), 2020년, p.452~485