Itertools - itertools.product()

요새 JavaScript에서 Iterable에 대해서 배우고 있어서 파이썬의 itertools를 다루는 문제를 풀어보았다.

문제 풀이

Cartesian product라는 것을 계산해주는 itertools.product()를 써보자.

문제 해석

Cartesian product는 데카르트 곱이라고 하며, 집합 A와 집합 B를 곱한 집합이다. 이 문제에서는 두 개 이상의 집합이 인수로 들어갔을 때, 각 집합의 요소들이 오는 모든 경우의 수를 담은 튜플의 배열이 리턴된다.

Task

두 개의 리스트 A, B가 주어졌을 때 이들의 cartesian product인 AxB를 계산할 것.

1
2
3
A = [1, 2]
B = [3, 4]
AxB = [(1, 3), (1, 4), (2, 3), (2, 4)

Input Format

첫 줄은 A, 두번째 줄은 B 리스트의 요소들이 공백으로 구분되어 입력된다.

Output Format

데카르트 곱의 결과가 공백으로 구분된 튜플로 출력되어야 한다.

문제 풀이

이미 주어진 코드 해석

  • 놀랍게도 오랜만에 해커랭크가 친절하지 않게도 아무 코드도 주지 않았다. 주어졌다. itertools.product()를 쓰는 만큼 꿀빨지 말고 입력값 처리라도 내가 하라는 의미인 것 같다.
  • (절대 문제를 대충 읽어서가 아니라 그냥) 메서드를 쓰지 않고 직접 구현해보았다.

코드 작성하기

itertoolsproduct 메서드 사용하기

  • 해커랭크가 원했던 답은 아래와 같이 itertools.product() 사용하는 것.
    1
    2
    3
    4
    5
    6
    7
    from itertools import product

    a = list(map(int, input().split()))
    b = list(map(int, input().split()))
    AxB = list(product(a, b))

    print(*AxB)
  • 입력받은 인풋은 공백을 포함한 문자열이니 공백을 기준으로 나눠 배열에 담아주는 split()을 해주고, 그 배열의 요소를 하나하나 돌면서 int() 작업해주는 map함수를 사용했다. 그리고 map 객체는 list로 바꿔준다.
  • itertools의 메서드인 product를 사용하여 튜플이 들어있는 리스트를 받아 변수 AxB에 할당하고, 출력할 때는 풀어서 출력해줘야 하니까 asterisk 기호로 풀어준다.
  • 사실 print 인수로 모든 과정을 한줄에 다 때려박아도 상관없다만 문제에서 뭔가 나눠서 진행하게끔 하는 것 같아서 여러 줄이 되어버렸다.

중첩 for문으로 해결해보기

  • A 리스트의 첫 요소와 B 리스트의 모든 요소를 돌면서 하나하나 갖는 튜플을 한번씩 만들어 AxB 리스트에 append 해주고, 이 과정을 A 리스트를 순회하면서도 동일하게 해주면 되니까 중첩된 for loop을 사용하면 된다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    a = list(map(int, input().split()))
    b = list(map(int, input().split()))
    AxB = []

    for i in range(len(a)):
    for j in range(len(b)):
    AxB.append((a[i], b[j]))

    print(*AxB)
  • 이렇게 하면 두 개의 리스트에 대한 데카르트 곱을 구할 수 있다. 세개 이상의 리스트에 대해서는 아마 중첩의 개수가 들어갈 별도의 작업이 들어가야 할 것인데 바람직한지는 모르겠다.

느낀 점

  • 문제를 잘 읽으면 쉽고 빠르게 풀 수 있지만 문제를 대충 읽으면 그래도 대충 어떻게 돌아가는지 구현해볼 수 있다.