프로그래밍백엔드 Python 개발자

Python에서 zip() 함수가 어떻게 작동하는지 설명하고, 이를 사용하는 이유와 서로 다른 길이의 시퀀스를 처리할 때 고려해야 할 특성을 알려주세요.

Hintsage AI 어시스턴트로 면접 통과

답변.

질문 역사
zip() 함수는 여러 시퀀스를 함께 '재봉'하여 해당 요소가 포함된 튜플로 변환하는 편리한 방법으로 Python에 등장했으며, 일종의 '행렬' 구조를 얻을 수 있습니다.

문제
개발자가 zip을 서로 다른 길이의 시퀀스에 적용할 때 오류가 발생하며, 그 결과가 가장 긴 시퀀스 길이가 될 것이라고 예상하거나 불완전한 변환을 사용하여 잘못된 언패킹을 수행합니다.

해결 방법
zip()는 하나 이상의 시퀀스를 받아들이고, n번째 튜플은 모든 시퀀스에서 n번째 요소를 포함하는 튜플을 반환하는 이터레이터를 반환합니다. 이터레이션은 가장 짧은 시퀀스가 소진될 때 종료됩니다.

코드 예:

names = ['John', 'Anna', 'Peter'] ages = [28, 22, 35] grouped = list(zip(names, ages)) print(grouped) # [('John', 28), ('Anna', 22), ('Peter', 35)]

주요 특징:

  • 지연 이터레이터를 반환하며, 메모리에 전체 목록을 생성하지 않습니다.
  • 가장 짧은 시퀀스까지 이터레이션이 진행됩니다.
  • zip(*...)를 통해 데이터를 쉽게 '펼칠' 수 있습니다.

속임수 질문.

zip에 서로 다른 길이의 시퀀스를 전달하면 어떻게 될까요?

결과는 가장 짧은 시퀀스의 길이입니다. 다른 요소는 무시됩니다.

zip([1,2,3], ['a','b']) # [(1,'a'), (2,'b')]

zip을 '펼칠' 수 있나요? 원래 시퀀스를 어떻게 다시 얻을 수 있을까요?

네, 별표 언패킹과 zip(*iterator)를 사용하면 가능합니다:

pairs = [(1, "a"), (2, "b")] numbers, letters = zip(*pairs) print(numbers) # (1, 2)

zip와 itertools.zip_longest의 차이점은 무엇인가요?

itertools의 zip_longest는 가장 긴 시퀀스까지 작업을 수행하며, 빈 부분을 지정된 fillvalue로 채웁니다.

from itertools import zip_longest zip_longest([1,2], ['a','b','c'], fillvalue=None) # [(1,'a'), (2,'b'), (None, 'c')]

일반적인 오류 및 안티 패턴

  • zip이 최대 길이에 따라 쌍을 생성할 것이라는 기대.
  • 빈 시퀀스에서의 예상치 못한 행동: zip은 즉시 비어있음.
  • Python 3에서 목록으로 변환하지 않고 zip을 사용하는 것: zip은 이터레이터로, 순회 후 소진될 수 있습니다.

실제 예시

부정적 사례

사용자와 비밀번호 쌍을 zip을 통해 처리했지만 리스트의 길이가 달랐습니다. 몇몇 사용자가 짧은 리스트로 인해 고려되지 않았습니다.

장점:

  • 간결한 코드.

단점:

  • 정보 손실.
  • 데이터 손실 이유를 디버깅하기 어려움.

긍정적 사례

시험 결과와 학생 이름을 결합하기 위해 zip_longest와 fillvalue="n/a"를 사용하여 모든 참가자의 데이터를保存했습니다.

장점:

  • 누락된 부분이 명확하게 보임.
  • 처리 과정에서 누군가 잃지 않음.

단점:

  • 추가 모듈을 import해야 함.