zip함수

매일 공부(ML)·2022년 5월 31일
0

이어드림

목록 보기
62/146

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


zip을 사용하기 전

리스트 컴프르헨션을 사용하면 소스 list에서 새로운 list를 파생되기 쉽다


names = [ ' Cecilia ' , ' 남궁만수' , ' abc' ]
counts = [len(n) for n in names]
print(count) #[7,4,3]

두 리스트를동시에 이터레이션할 경우 names 소스 리스트의 길이를 사용해서 이터레이션할 수 있다.(with 인덱싱)

  • 시각적 잡음이 많다.

  • 인덱스를 사용해 names와 counts의 원소를 찾는 과정을 어렵게 한다.

  • 배열 인덱스 i를 사용하여 배열 원소를 가져오는 연산이 두 번 일어난다.

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

range보단 enumerate사용하라(batter way07)

  • range보다는 낫지만 이상적인 코드는 아니다.
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는 다른 원소를 추가해도 출력이 되지 않는다.

    	- zip는 자신이 감싼 이터레이터 중 어느 하나가 끝날 때까지 튜플을 내놓은다.
    
    	- 출력은 가장 짧은 입력의 길이와 같다.

names.append('Rosalind')
for name, count in zip(names,counts):
    print(name)

#결과
Cecilia
남궁만수
abc

  • 리스트 컴프리헨션으로 리스트를 파생시킨 경우 각 리스트의 길이가 같은 경우가 많다.

  • 긴 이터레이터의 뒷부분을 버리는 zip기능이 바람직하지 못하는 경우도 있다.

    	- 가장 짧은 이터레이터에 맞춰 길이를 제한하지 않고 길이가 서로 다른 이터레이터에 대해 루프를 수행하려면 itertools 내장 모듈의 zip_longes함수 사용
    
    	- 만약 리스트의 길이가 같지 않다면 itertools 내장 모듈에 들어 있는 zip_longest 대신 사용하는 것을 고려한다.

import itertools

from name, count in itertools.zip_longest(names, counts):
    print(f'{name}: {count}')

Cecilia: 7 
남궁민수: 4 
abc: 3 
Rosalind: None
  • zip_longest는 존재하지 않는 값을 fillvalue로 대신한다.

    	- fillvalue의 default는 None이다.
profile
성장을 도울 아카이빙 블로그

0개의 댓글