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 으로 반환 한다.