iterator와 generator 기초개념

2019-05-21

.

그림, 실습코드 등 학습자료 출처 : https://gitlab.com/radajin

iterator&generator를 위해서는 먼저 iterable을 알아야 한다.

1. iterable 개요

iterable은 순서가 있는 집합을 의미한다.

x = [1,2,3]
it = iter(x)

## x에 있는 데이터를 하나씩 꺼내는 것이 목적인게 iter이다.
print(next(it))
1
print(next(it))
2
print(next(it))
3
print(x)
[1, 2, 3]
  • iterator란 next 함수를 호출하면 다음 값을 생성하는 생성기이다.

  • next를 호출하면 객체상태가 변경된다.

2. iterator를 이용한 피보나치 수열 구현

# 피보나치 수열을 구현한 이터레이터
# next를 호출하면 객체의 상태를 변경한다.
# 호출에 대한 결과값을 return 한다.

class fib:
    def __init__(self):
        self.prev = 0
        self.current = 1
        
    def __iter__(self):
        return self ##오브젝트 자체를 리턴한다.
    
    def __next__(self):
        value = self.current
        self.current += self.prev
        self.prev = value
        return value
    
f = fib()

for count in range(10):
    print(next(f), end = ' ')
1 1 2 3 5 8 13 21 34 55 

3. generator 개요

  • 이터레이터를 간편하게 만든것이 제네레이터이다.

  • 특별한 종류의 이터레이터라고 생각하면 된다.

  • 이터레이터를 간결하게 만든것이다.

  • iter()와 next() 메서드로 클래스를 작성하는 수고를 없애줬다.

  • 사용하는 이유 : 프로그램의 성능향상 때문이다. 왜냐하면 메모리를 소비하지 않기 때문이다. 또한 속도도 빨라진다. lazy evaluation이 가능하기 때문이다.

  • 특정한 종류의 함수이다.

  • next로 실행한다.

  • yield를 순차적으로 실행한다. 예를 들어 내가 yield 1을 반환했다면 그다음에는 yield 2를 반환한다. yield 1을 반환하는게 아니라..

4. generator를 이용한 피보나치수열 구현

def fib():
    prev = 0
    current = 1
    ## 아래처럼해도 가능
    ## prev, current = 0,1
    while True:
        yield current
        ## yield는 yield 명령을 만나면 값을 바깥으로 전달한다.
        ## 그리고 현재 실행하던 함수를 잠시 중단하고 바깥 코드를 실행한 후에 다음 next를 만나면 다시 돌아와서 나머지 코드를 실행한다.
        prev, current = current, prev + current
        
f = fib()

for count in range(10):
    print(next(f), end = ' ')
1 1 2 3 5 8 13 21 34 55 

yield 테스트

def test():
    yield 1
    yield 2
    yield 3
    yield 4
    yield 5
    
t = test()

for count in range(5):
    print(next(t))

## 실행코드에 넥스트에 넣어줬을때 순서대로 리턴해줌
1
2
3
4
5
  • yield, yield from

1) yield를 만나면 값을 바깥으로 전달

2) 현재 함수를 잠시 중단하고 바깥 코드를 실행 시킴

def test():
    ls = [1, 2, 3]
    yield from ls
    
t = test()

for _ in range(3):
    print(next(t))
1
2
3

5. list Comprehention

  • 컴프리헨션도 제너레이터의 한 종류이다.
# list comprehention
numbers = [1, 2, 3, 4, 5, 6]
[x * x for x in numbers]
[1, 4, 9, 16, 25, 36]
# set comprehention
numbers = [1, 2, 3, 4, 5, 6]
{x * x for x in numbers}
{1, 4, 9, 16, 25, 36}
# dictionary comprehention
numbers = [1, 2, 3, 4, 5, 6]
{x: x * x for x in numbers}
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36}
  • 제너레이터 표현식
numbers = [1, 2, 3, 4, 5, 6]
gen_numbers = (x * x for x in numbers)
print(gen_numbers)
<generator object <genexpr> at 0x10d272468>
next(gen_numbers)
1
list(gen_numbers)
[4, 9, 16, 25, 36]