DL Study
[파이썬에서 살아남는법 제 7장] 여러 이터레이터에 대해 나란히 루프를 수행하려면 zip 을 사용하라
형혹성
2023. 1. 17. 17:30
※본 내용은 파이썬의 코딩 기술 (개정 2판)을 바탕으로 작성 했습니다.
리스트 컴프리헨션을 사용하면 소스 list 에 새로운 list 를 파생시키기 쉽다.
names = ['Cecilia', 'Lise', 'Marie']
counts = [len(n) for n in names]
print(counts)
>>>
[7, 4, 5]
만들어진 list 는 소스와 같은 인덱스 위치에 있는 원소와 관련이 있다. 두개를 동시에 이터레이션 할 경우 name 소스 리스트의 길이를 사용해 할수 있다.
longest_name = None
max_count = 0
for i in range(len(names)):
count = counts[i]
if count > max_count:
longest_name = names[i]
max_count = count
print(longest_name)
>>>
Cecilia
문제는 시각적으로 잡음이 많다.
그래서 enumerate 를 사용한 코드도 있다.
for i, name in enumerate(names):
count = counts[i]
if count > max_count:
longest_name = name
max_count = count
근데 이것도 쫌... 보기 안깔끔 하다.
그래서 파이썬의 zip 이라는 내장함수를 사용해본다.
zip 은 둘 이상의 이터레이터를 ㅈ지연계산 제너레이터를 사용해 묶어 준다.
그리고 다음값이 들어있는 튜플에 반환 한다.
이 튜플을 for 문에서 바로 언패킹 한다.
for name, count in zip(names, counts):
if count > max_count:
longest_name = name
max_count = count
zip 의 주의상황
names.append('Rosalind')
for name, count in zip(names, counts):
print(name)
>>>
Cecilia
Lise
Marie
names 에 새로 추가한 Rosalind는? zip 은 감싼 이터레이터 중 하나가 끝나면 끝난다.
길이가 같다면 완벽하겠지만 길이가 짧은 쪽에 맞춰지는 형식이다.
하지만 길이가 같지 않을것으로 예상되면 itertools 모듈의 zip_longest 를 사용 해라
import itertools
for name, count in itertools.zip_longest(names, counts):
print(f'{name}: {count}')
>>>
Cecilia: 7
Lise: 4
Marie: 5
Rosalind: None
zip_longest 는 존재하지 않는 값(상대적 길이가 짧은값) 을 None 으로 반환 한다.