백준으로 n과 m 시리즈를 파이썬으로 풀고 있습니다. itertools를 쓰면 꽤 편하게 풀 수 있는데요. 이 중에서 이번 시간에는 starmap에 대해서 간단하게 알아보고자 합니다.


 

 설명 먼저 봅시다. func이랑 iterable한 무언가를 넣는다고 되어 있어요. 리턴하는 것은 iterator라고 해요. 그런데 어떤 것을 리턴하나요? function evaludated가 된 무언가를 돌려준다 되어 있는데요. 이것만 봐서는 얘가 무엇을 하는 친구인지 잘 와닿지 않아요. 대신에 문서를 보면 Roughly equivalent to 부분이 있어요. 그 밑에 있는 코드를 보면서 이해하는 게 더 빠를 거 같아요.

 

 

 이런 코드가 있는데요. 일단 iterable 하다는 것은 next로 계속 뽑아올 수 있다는 것을 의미합니다. 2번째 줄은 그렇다면 순회를 하면서 무언가를 하겠다는 의미가 됩니다.

 

 

 iterable 한 것이 list라고 해 봅시다. 그러면 args는 for loop를 돌 때 마다 (1, 2), (1, 3), ... 이런 식으로 될 텐데요. yield가 있어요. 잠깐. 이거는 뭘까요? 제가 이 글에도 설명을 드리긴 했습니다만, 실행을 양보하는 무언가라고 할 수 있어요. 어떻게요?

 

 

 yield가 나온 순간 호출한 쪽으로 넘겨버립니다. 그리고 다음에 generator가 호출이 될 때 다시 yield 다음 부분부터 시작됩니다. 백준 15649번 문제를 이 메서드와 itertools를 이용해서 풀어봅시다. 

 


 먼저, n개 중 m개를 뽑는데 순서 상관 있는 것은 permutation입니다. 그래서, itertools의 permutation을 쓰면 되고요. 코드를 짧게 하기 위해서, starmap 함수를 썼는데요. n이 4이고 m이 2라면, it.permutations는 (1, 2), (1, 3), (1, 4), (2, 1), (2, 3), (2, 4), (3, 1), ... 이런 순서대로 나오는, iterable 한 무언가일 겁니다.

 

 그런데 starmap 함수의 내부를 보면 iterable한 무언가를 순회하면서 yield function(*args)를 호출하는데요.

 

 

 그러면, 상황은 요래 그려지게 됩니다. 즉, starmap이 호출이 되면, yield print(*(1, 2))까지 실행되고, 그 다음에 또 호출이 되면, 그 후부터 yield print(*(1, 3))까지 실행되고 그렇게 될 겁니다.

 

 

 즉, 이 함수가 실행이 될 때 print(*(1, 2))가 실행되고, 또 실행 되면 print(*(1, 3))이 실행이 되어 버립니다.

 

 이 프로그램의 결과는 위와 같습니다. print(*(1, 2))는 1과 2가 공백으로 구분되어 출력됩니다. 그러면 n이 4이고 m이 2일 때, 문제의 함수 starmap의 1번째 인자에 print를 넘기고, 2번째 인자에 permutation의 결과를 넣어버리면 요래 나올 겁니다.

 

 

 이는 문제에서 원하는 결과값과 같음을 알 수 있습니다. 즉, itertools의 starmap은 인자로 넘겨준 iterable한 것에 대해서, 각각의 원소들에 대해서 병렬적으로 변환을 적용하는 무언가라고 할 수 있습니다.

 


 그러면 이 프로그램은 뭘 하는 것일까요? starmap에 li를 넘겼습니다. iterable 한가요? 다음에 변환 장치는 pow입니다. 결국, (1, 2)와 (3, 4)에 대해서 pow 라는 변환을 적용한 결과들을 리턴하게 됩니다.

 

 

 1의 2승은 1, 3의 4승은 81입니다. 변환이 잘 적용되었음을 알 수 있습니다.