#!/usr/bin/env python # coding: utf-8 # # 8. 여러 이터레이터에 대해 나란히 루프를 수행하려면 zip을 사용하라 # 리스트 컴프리헨션을 사용하면 소스 list에서 새로운 list를 파생시키기 쉽다. # In[1]: names = ['Cecilia', '남궁민수', '어쩌고'] counts = [len(n) for n in names] print(counts) # 두 리스트를 동시에 이터레이션할 경우 names 소스 리스트의 길이를 사용해 이터레이션할 수 있다. # In[2]: longest_name = None max_count = 0 # In[3]: for i in range(len(names)): count = counts[i] if count > max_count: longest_name = names[i] max_count = count print(longest_name) # 어지럽다 # # enumerate를 사용해보자 # In[4]: for i, name in enumerate(names): count = counts[i] if count > max_count: longest_name = name max_count = count # zip을 사용해보자 # # zip은 둘 이상의 이터레이터를 지연 계산 제너레이터를 사용해 묶어준다. # In[5]: for name, count in zip(names, counts): if count > max_count: longest_name = name max_count = count # zip은 자신이 감싼 이터레이터 중 어느 하나가 끝날때까지 튜플을 내놓는다. # In[6]: names.append('Rosalind') # In[7]: for name, count in zip(names, counts): print(name) # zip에 전달한 리스트의 길이가 같지 않을 것으로 예상한다면 itertools 내장 모듈에 들어 있는 **zip_longest**를 대신 사용하는 것을 고려하라. # In[8]: import itertools for name, count in itertools.zip_longest(names, counts): print(f'{name}: {count}') # zip_longest는 존재하지 않는 값을 자신에게 전달된 fillvalue로 대신한다. 디폴트는 None이다 # In[11]: for name, count in itertools.zip_longest(names, counts, fillvalue=1): print(f'{name}: {count}') # ## 기억해야 할 내용 # - zip 내장 함수를 사용해 여러 이터레이터를 나란히 이터레이션할 수 있다. # - zip은 튜플을 지연 계산하는 제너레이터를 만든다. 따라서 무한히 긴 입력에도 zip을 쓸 수 있다. # - 입력 이터레이터의 길이가 서로 다르면 zip은 아무런 경고도 없이 가장 짧은 이터레이터 길이까지만 튜플을 내놓고 더 긴 이터레이터의 나머지 원소는 무시한다. # - 가장 짧은 이터레이터에 맞춰 길이를 제한하지 않고 길이가 서로 다른 이터레이터에 대해 루프를 수행하려면 itertools 내장 모듈의 zip_longest 함수를 사용하라.