여러 이터레이터에 대해 나란히 루프를 수행하려면 zip을 사용하라

Minsang Yu·2023년 6월 6일
0

파이썬에서는 관련된 객체가 들어 있는 리스트를 다수 다루는 경우가 자주 있다. 리스트 컴프리헨션을 사용하면 소스 list에서 새로운 list를 파생시키기 쉽다.

names = ['Cecilia', '남궁민수', 'John']
counts = [len(n) for n in names]

# 만들어진 name중 가장 긴 이름을 리턴하라

longest_name = None
max_count = 0

for i in range(len(names)):
    count = counts[i]
	  if count > max_count:
        longes_name = name[i]
        max_count = count

print(longest_name)

>>>
Cecilia

문제는 이루프가 시각적으로 잡음이 많다는 것이다. 인덱스를 사용해 names와 counts의 원소를 찾는 과정이 코드를 읽기 어렵게 만든다. 배열 인덱스 i를 사용해 배열 원소를 가져오는 연산이 두번 일어난다.


  • 이런 코드를 더 깔끔하게 만들 수 있도록 파이썬은 zip이라는 내장함수를 제공한다.
  • zip은 둘 이상의 이터레이터를 지연 계산 제네레이터를 사용해 묶어준다.
  • zip 제네레이터는 각 이터레이터의 다음 값이 들어 있는 튜플을 반환한다.
  • 이 튜플을 for 문에서 바로 언패킹 할 수 있다.
names = ['Cecilia', '남궁민수', 'John']
counts = [len(n) for n in names]

# 만들어진 name중 가장 긴 이름을 리턴하라

longest_name = None
max_count = 0

for name, count in zip(names, countes):
    if count > max_count:
        longest_name = name
				max_count = count 

이렇게 만든 코드는 인덱스를 사용해 여러 리스트의 원소에 접근하는 코드보다 훨씬 깔끔하다.

zip은 자신이 감싼 이터레이터 원소를 하나씩 소비한다. 따라서 메모리를 다 소모해서 프로그램이 중단되는 위험 없이 아주 긴 입력도 처리할 수 있다.

zip의 주의사항

zip은 인자로 받은 이터레이터중 가장 짧은 이터레이터 길이에 맞춰서 반환한다.

names.append('Rosalind')

for name, count in zip(names, countes):
    print(name)

>>>
Cecilia
남궁민수
John

새로 추가한 원소인 Rosalind 에 대한 출력이 없다. zip은 자신이 감싼 이터레이터중 어느 하나가 끝날 때까지 튜플을 내놓기 때문이다.

긴 이터레이터를 버릴떄가 바람직하지 않을 경우 itertoos.zip_longest

를 사용한다.

import itertoos

for name, count in itertools.zip(names, countes):
				print(f"{name}: {count}")

>>>
Cecilia: 7
남궁민수: 4
John: 4
Rosalind: None # 존재하지 않는 이터레이터 원소는 null처리한다.

zip_longest는 존재하지 않는값을 자신에게 전달된 fillvalue로 대신한다. fillvalu의 기본값은 None이다.

정리

  • zip 내장 함수를 사용해 여러 이터레이터를 나란히 이터레이션할 수 있다.
  • zip은 튜플을 지연 계산하는 제네레이터를 만든다. 따라서 무한히 긴 입력에도 zip을 쓸 수 있다.
  • 입력 이테레이터의 길이가 서로 다르면 zip은 아무런 경고도 없이 가장 짧은 이터레이터 길이까지만 튜플을 내놓고 더 긴 이터레이터의 나머지 원소는 무시한다.
  • 가장 짧은 이터레이터에 맞춰 길이를 제한하지 않고 길이가 서로 다른 이터레이터에 대해 루프를 수행하려면 itertools 내장 모듈인 zip_longest 함수를 사용하라.

Reference. Effective Python

profile
Jr. DataEngineer

0개의 댓글