[Python] zip(), itertools.combinations()

sunclock·2021년 1월 3일
0

코딩테스트

목록 보기
3/3
post-thumbnail

문제

전화번호부 문자열 리스트 안에서 시작하는 문자(열)이 동일한 원소의 존재 유무 검사

예시 입력:

['123', '456', '789']

['119', '119435', '432']

['251', '563', '2513']

예시 출력:

True
False
False

내가 푼 답

검사 기준이 되는 접두어 원소는 검사 대상이 되는 원소보다 길이가 항상 작다.
불필요한 검사를 막기 위해 sorted(key=len)으로 길이를 기준으로 리스트를 오름차순 정렬했다.

    phone_book.sort(key=len)
    prefix_idx = 0
    while prefix_idx < len(phone_book):
        for idx in range(prefix_idx+1, len(phone_book)):
            if phone_book[idx].startswith(phone_book[prefix_idx]):
                return False
        prefix_idx += 1
    return True 

다른 사람이 푼 답

파이썬 내장 함수인 zip을 사용했다.
zip을 사용하면 길이가 다른 리스트에서 예외 발생 없이 원소를 튜플로 짝지을 수 있다.
값을 기준으로 sort했기 때문에 for, if문을 사용해 i번째 원소와 i+1번째 원소만 검사하면 된다.
while, for, if문을 동시에 사용해야 했던 내 코드보다 읽기 쉽고 간단하다.

>>>['119', '911234', '11943'].sort()
['119', '11943', '911234']
def solution(phoneBook):
    phoneBook = sorted(phoneBook)
    for p1, p2 in zip(phoneBook, phoneBook[1:]):
        if p2.startswith(p1):
            return False
    return True

itertools.zip()

각 iterables 의 요소들을 모으는 이터레이터를 만듭니다.

튜플의 이터레이터를 돌려주는데, i 번째 튜플은 각 인자로 전달된 시퀀스나 이터러블의 i 번째 요소를 포함합니다. 이터레이터는 가장 짧은 입력 이터러블이 모두 소모되면 멈춥니다. 하나의 이터러블 인자를 사용하면, 1-튜플의 이터레이터를 돌려줍니다. 인자가 없으면, 빈 이터레이터를 돌려줍니다.

zip() 에 길이가 같지 않은 입력들을 제공하는 것은, 끝부분에서 매치되지 않고 남는 더 긴 이터러블들의 값들에 신경 쓰지 않는 경우로 제한해야 합니다. 그 값들이 중요하다면, 대신 itertools.zip_longest() 를 사용하세요.

zip()을 * 연산자와 함께 쓰면 리스트를 unzip 할 수 있습니다:

>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
>>> list(zipped)
[(1, 4), (2, 5), (3, 6)]
>>> x2, y2 = zip(*zip(x, y))
>>> x == list(x2) and y == list(y2)
True

itertools.zip_longest(*iterables, fillvalue=None)

iterables의 각각에서 요소를 집계하는 이터레이터를 만듭니다. 이터러블들의 길이가 고르지 않으면, 누락된 값이 fillvalue로 채워집니다. 가장 긴 이터러블이 소진될 때까지 이터레이션이 계속됩니다.

>>>zip_longest('ABCD', 'xy', fillvalue='-')
Ax By C- D-

이터러블 중 하나가 무한할 수 있으면, zip_longest() 함수는 호출 수를 제한하는 것으로 감싸야 합니다 (예를 들어 islice()나 takewhile()). 지정하지 않으면, fillvalue의 기본값은 None입니다.

itertools.islice(iterable, start, stop[, step])

>>>islice('ABCDEFG', 2)
A B
>>>islice('ABCDEFG', 2, 4)
C D
>>>islice('ABCDEFG', 2, None)
C D E F G
>>>islice('ABCDEFG', 0, None, 2)
A C E G

itertools.takewhile(predicate, iterable)

>>>takewhile(lambda x: x<5, [1,4,6,4,1])
1 4

itertools.combinations(iterable, r)

입력 iterable에서 요소의 길이 r 부분 집합들을 반환합니다.

조합(combination) 튜플은 입력 iterable의 순서에 따라 사전식 순서로 방출됩니다. 따라서, 입력 iterable이 정렬되어있으면, 조합 튜플이 정렬된 순서로 생성됩니다.

요소는 값이 아니라 위치로 고유성을 다룹니다. 따라서 입력 요소가 고유하면, 각 조합에 반복 값이 없습니다.

>>>combinations('ABCD', 2)
AB AC AD BC BD CD
>>>combinations(range(4), 3)
012 013 023 123

itertools.combinations_with_replacement(iterable, r)

입력 iterable에서 요소의 길이 r 부분집합들을 반환하는데, 개별 요소를 두 번 이상 반복할 수 있습니다.

>>>combinations_with_replacement('ABC', 2)
AA AB AC BB BC CC

출처

프로그래머스 코딩테스트 연습 해시 '전화번호 목록'
파이썬 3.9.1 공식 문서

profile
안녕하세요.

0개의 댓글