ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [코딩도장] day27. 파이썬 이터레이터 사용하기 - __iter__, __next__, __getitem__
    IT/파이썬 2020. 9. 21. 22:07

    출처 : unsplash

     

    ■ 들어가기

    - 파이썬 코딩 도장 (남재윤/길벗). 을 공부하며 정리하는 블로그


    ▶ Unit39. 이터레이터 사용하기

         - 39.1 반복 가능한 객체 알아보기

         - 39.2 이터레이터 만들기

         - 39.3 인덱스로 접근할 수 있는 이터레이터 만들기

         - 39.4 iter, next 함수 활용하기

     

    0. 들어가기

    - 이터레이터(iterator) : 값을 차례대로 꺼낼 수 있는 객체(object)
    - for 반복문에서 "for i in range(100) :" 를 통해 0 ~ 99까지 연속된 숫자를 만들 때 사실 이터레이터 하나 생성 후 반복하여 숫자를 하나씩 꺼내면서 반복 처리
    - 숫자가 많은 경우 메모리를 많이 사용하게 되어 성능 상 문제될 수 있음
    - 이를 해결하기 위해 이터레이터만 생성하고 값이 필요한 시점에 값을 만드는 방식 사용 (지연 평가, lazy evaluation)

     

    >> 39.1 반복 가능한 객체 알아보기 <<

    - 반복 가능한 객체(iterable) : 요소가 여러 개 들어있고, 한 번에 하나씩 꺼낼 수 있는 객체
    - 즉, 문자열, 리스트, 튜플, 딕셔너리, 세트, range 등 반복 가능한 객체
    - 사용법 : dir(객체)
    - 객체가 반복 가능한 객체인지 확인 방법 : 객체에 __iter__ 메서드가 들어있는지 확인!
    - 리스트의 이터레이터를 변수에 저장 후 __next__ 메서드를 호출하면 요소를 차례대로 꺼낼 수 있음
    - __next__ 로 더이상 꺼낼 요소가 없는 경우 StopIteration 예외 발생

    >>> it = [1, 2, 3].__iter__()
    >>> it.__next__()
    1
    >>> it.__next__()
    2
    >>> it.__next__()
    3
    >>> it.__next__()
    Traceback (most recent call last):
      File "<pyshell#5>", line 1, in <module>
        it.__next__()
    StopIteration

     

    1. for와 반복 가능한 객체

    출처 : 파이썬 코딩 도장 (dojang.io)

     

    >> 39.2 이터레이터 만들기 <<

    - __iter__, __next__ 메서드를 구현해서 range(횟수)와 같이 동작하는 기능
    - 사용법
    class 이터레이터이름 :
        def __iter__(self) :
            코드


        def __next__(self) :
            코드

    목적 : 함수 내 __iter__, __next__ 메서드 구현  
    소스 (iterator.py) 결과
    class Counter :
        def __init__(self, stop) :
            self.current = 0    # 현재 숫자 유지, 0부터 지정된 숫자까지 반복
            self.stop = stop    # 반복을 끝낼 숫자

        def __iter__(self) :
            return self         # 현재 인스턴스를 반환

        def __next__(self) :
            if self.current < self.stop :   # 현재 숫자가 반복을 끝낼 숫자보다 작을 때
                r = self.current            # 반환할 숫자를 변수에 저장
                self.current += 1           # 현재 숫자를 1 증가
                return r                    # 숫자를 반환
            else :
                raise StopIteration         # 예외 발생

    for i in Counter(3) :
        print(i, end=' ')
    0 1 2

     

    1. 이터레이터 언패킹

    - 언패킹(unpacking) : 함수의 인자로 리스트, 튜플 등 객체를 인자로 넘겨서 사용하는 방법  (Unit 30. 참고)
    - 이터레이터도 언패킹이 가능하며 단, 이터레이터의 반복횟수와 변수의 개수는 같아야 함!

    >>> a, b, c = Counter(3)
    >>> print(a, b, c)
    0 1 2
    >>> a, b, c, d, e = Counter(5)
    >>> print(a, b, c, d, e)
    0 1 2 3 4

     

     

    >> 39.3 인덱스로 접근할 수 있는 이터레이터 만들기 <<

    - __getitem__ 메서드 구현
    - 사용법
    class 이터레이터이름 :
        def __getitem__(self, 인덱스) :
            코드

    목적 : __getitem__ 메서드 구현으로 인덱스 접근
    소스 (iterator_getitem.py) 결과
    class Counter :
        def __init__(self, stop) :
            self.stop = stop

        def __getitem__(self, index) :
            if index < self.stop :
                return index
            else :
                raise IndexError

    print(Counter(3)[0], Counter(3)[1], Counter(3)[2])

    for i in Counter(3) :
        print(i, end=' ')
    0 1 2
    0 1 2 

     

     

    >> 39.4 iter, next 함수 활용하기 <<

    - 파이썬 내장함수 iter는 __iter__ 메서드를 호출, next는 __next__ 메서드를 호출
    - iter : 반복 가능한 객체에서 이터레이터를 반환
    - next : 이터레이터에서 값을 차례대로 꺼냄

    >>> it = iter(range(3))
    >>> next(it)
    0
    >>> next(it)
    1
    >>> next(it)
    2
    >>> next(it)
    Traceback (most recent call last):
      File "<pyshell#37>", line 1, in <module>
        next(it)
    StopIteration

     

    1. iter

    - iter는 반복을 끝낼 값을 지정하면 특정 값이 나올 때 반복을 종료
    - 이 경우 반복 가능한 객체(iterable) 대신에 호출 가능한 객체(callable)를 넣어주며, 반복을 끝낼 값은 sentinel이라 부름
    - 사용법 : iter(호출가능한객체, 반복을끝낼값)
    - 예제: 0~5까지 무작위 숫자 생성 시 2 나오면 반복 종료

    >>> import random
    >>> it = iter(lambda : random.randint(0, 5), 2)
    >>> next(it)
    0
    >>> next(it)
    1
    >>> next(it)
    Traceback (most recent call last):
      File "<pyshell#46>", line 1, in <module>
        next(it)
    StopIteration

    # for문과 함께 사용
    >>> import random
    >>> for i in iter(lambda : random.randint(0, 5), 2) :
    print(i, end=' ')


    5 3 3 3 0 5 4 

     

    2. next

    - next는 기본값 기정 가능하며, 반복이 끝나더라도 StopIteration 예외 발생하지 않고 기본값 출력 가능
    - 사용법 : next(반복가능한객체, 기본값)

    >>> it = iter(range(3))
    >>> next(it, 10)
    0
    >>> next(it, 10)
    1
    >>> next(it, 10)
    2
    >>> next(it, 10)
    10
    >>> next(it, 10)
    10

     

    댓글

Designed by Tistory.