Iterator, Generator

JM·2020년 6월 1일
0

Python

목록 보기
4/5

Iterator

  • 이터레이터는 값을 순차적으로 꺼내올 수 있는 객체입니다.

  • iterator는 iterable한 객체를 내장함수 또는 iterable객체의 메소드로 객체를 생성할 수 있습니다.

  • 파이썬 내장함수 iter()를 사용해 iterator 객체를 생성 할 수 있습니다.

  • Iterator는 iter 함수의 인자로 Iterable을 적용해 반환된 객체로, 값을 하나씩 반환하며 그 상태값을 유지, 관리하는 객체의 개념입니다.

  • terator는 Iterable에 iter 내장 함수를 적용해 반환되는 객체로서 next 함수를 통해 값을 한 번에 한 번씩 반환하는 특징이 있습니다. 내부적으로 현재까지의 반환 상태를 관리하고 조건에서 정의한 마지막까지 반환하면 더 사용할 수 없으며 StopIteration 예외 발생시킵니다.

Generator

  • Generator는 나만의 Iterable, Iterator 기능을 만들되, 생성 문법을 기존보다 단순화한 개념 또는 클래스라고 할 수 있습니다.
  • Iterable, Iterator 생성 문법을 간략화한 개념 및 구현이기 때문에 그 내부과정이 직관적으로 보이지는 않지만(추상화되었기 때문에), 함수의 호출 결과가 결국은 Iterator protocol을 준수하는 개체를 반환한다고 이해하면 무난하다.

lazy evaluation 이란 무엇인지와 장점 및 리스트 컴프리헨션과의 차이??

Lazy Evaluation은 어떤 값이 실제로 쓰일 때 까지 그 값의 계산을 뒤로 미루는 동작 방식입니다.

밑에 코드 예제를 통해 알아보겠습니다.

import time

def print_iter(iter):
for element in iter:
print(element)
def lazy_return(num):
print("sleep 1s")
time.sleep(1)
return num

print("comprehension_list=")
comprehension_list = [ lazy_return(i) for i in L ]
print_iter(comprehension_list)

print("generator_exp=")
generator_exp = ( lazy_return(i) for i in L )
print_iter(generator_exp)

해당 코드를 실행시켜보면

print_iter(comprehension_list)
1
2
3
print_iter(generator_exp)
sleep 1s
1
sleep 1s
2
sleep 1s
3

이러한 결과를 확인할 수 있습니다. 프린트 결과를 떠나 어떤 방식으로 작동이 되는지가 중요합니다.

첫 번째에서는 list가 반환돼서 쓰였고, 두 번째에서는 Generator가 반환돼 쓰였는데, 이 둘에는 큰 차이가 있는데 내부적으로 컴퓨터 메모리와 관련이 있습니다.

  1. 첫번째 (list comprehension) 코드를 입력했을 때 메모리에 배열의 크기에 비례하는 공간이 바로 할당이 됩니다.
  2. 두번째 (generator expression)는 지정한 규칙대로 값을 반환할 규칙과 현재 어디까지 반환했는지 등을 관리할 여러 상태값을 담고 있지만 배열과 달리 값 모두를 generator를 생성할 당시에 메모리에 할당하지 않는다는 결정적인 차이가 있습니다.

generator(iterator)를 통해 할 수 있는 모든 일은 list comprehension(기본 list)으로 가능한데 "왜 굳이 나눠서 사용을 할까?"

  1. list 같은 자료구조는 내부 데이터의 크기에 따라 총 크기가 결정되므로 저렇게 큰 크기의 list를 선언하면, 일반 컴퓨터의 한정된 용량의 메모리로는 감당할 수 없기 때문입니다.

  2. 그에 반해 iterator, generator 일련의 값을 사용할 때 모든 데이터를 메모리에 모두 로딩하는 대신 한 값씩 필요할 때마다 로딩, 평가함으로써(lazy loading, evaluate) 메모리를 절약하고, 메모리 부족으로 프로그램이 실패하는 것을 방지할 수 있다는 점이 다릅니다.

매우 큰 파일을 읽는다거나, 네트워크를 통해 대용량의 데이터를 다운로드할 때를 생각해보면, 줄 등의 한 단위를 필요할 때 한 줄씩 평가하는(evaluate) lazy loading이 한 번에 모든 데이터를 loading하는 방식보다 안전한 것입니다. 따라서 상황에 맞게 사용하는 것이 필요할 것 같습니다.

출처 : https://shoark7.github.io/programming/python/iterable-iterator-generator-in-python

0개의 댓글