ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Python] yield 알아보기 ( generator )
    Python 2024. 4. 6. 10:36
    728x90
    반응형

     

    - 목차

     

    들어가며.

    이번 글에서는 파이썬의 yield 구문에 대해서 알아보려고 합니다.

    yield 는 파이썬의 함수 내부에서 사용되는 구문입니다.

    즉, 함수 외부에서는 사용할 수 없으며 그 성격이 return 키워드와 유사합니다.

    yield 가 사용된 함수는 generator 라고 불리게 되는데요.

    generator 는 iterator 를 손쉽게 만들어주는 파이썬의 내장된 기능입니다.

     

    이번 들에서는 yield 와 generator 그리고 이와 관련된 여러 예시들을 살펴볼 예정입니다.

     

     

    yield.

    yield 의 사전적인 의미는 "산출하다." 입니다.

    그리고 산출이란 무언가를 생산하고 그 결과를 외부로 제공한다는 의미를 가지죠.

    yield 는 함수에서만 사용되는 키워드인데요.

    yield 가 사용된 함수는 generator 라고 부릅니다.

    generator 는 main function 에서 사용될 수도 있고, 여러 함수 내부에서 call 될 수 있습니다.

    가령 아래와 같이 사용됩니다.

    test_generator 라는 함수는 main 함수 내부에서 아래와 같이 call 됩니다.

    def test_generator():
        yield 1
    
    def main() :
        generator = test_generator()
        value = next(generator)
        print(value)

     

    이 관계를 Caller Function 과 generator 라고 부르도록 하겠습니다.

    generator 는 "yield something" 문장에서 사용된 something 이라는 결과를 생산합니다.

    그리고 Caller Function 에게 제공합니다.

    위 예시에서는 test_generator 는 1을 산출하며, main function 은 산출된 1 이라는 값을 제공받습니다.

    즉, 1 을 생산해서 1을 Caller Function 에게 제공하게 되며 결론적으로 1을 산출합니다.

     

    yield 는 Iterator 로써 동작하도록 한다.

    위 예시에서는 사실상 yield 가 return 으로 대체될 수 있습니다.

    return 으로 대체되어도 그 결과는 동일하죠.

    yield 의 강점은 Iterator 로써 동작할때에 빛을 봅니다.

    return 함수를 종료시키는 키워드이지만, yield 는 함수를 종료시키지 않고 Caller Function 에게 연산 결과만을 제공합니다.

    그래서 generator 함수는 종료되지 않고 Caller Function 의 다음 호출을 기다리게 됩니다.

     

    generator 는 함수를 종료시키지 않고, 산출물만은 Caller Function 에게 제공합니다.

    그래서 중간 결과물을 유지하게 되고, 상태를 유지합니다.

    따라서 Caller Function 의 다음 호출 시에 이전 상태를 유지하기 때문에 Sequential 한 다음값을 제공합니다.

    즉, generator 는 태생적으로 Iterator 처럼 동작할 수 있습니다.

    1씩 증가하는 값을 제공하는 incremental_generator 가 존재한다고 할때에 Caller Function 의 호출마다

    내부 상태값인 counter 는 1씩 증가하게 되며, counter 는 그 값을 변경하고 유지합니다.

    def incremental_generator():
        counter = 1
        while True:
            yield counter
            counter += 1
    
    generator = incremental_generator()
    value = next(generator)
    print(value)
    value = next(generator)
    print(value)
    value = next(generator)
    print(value)
    value = next(generator)
    print(value)

     

    < 출력 결과 >

    1
    2
    3
    4

     

    yield 는 메모리를 절약합니다.

    파이썬의 Iterable 타입의 자료구조 중에서 list, dict, tuple 등은 모든 값들을 메모리에 저장합니다.

    간단한 예로써 sys.getsizeof(list(range(0, 10000))) 와 같은 함수를 통해서 메모리에 로드된 데이터의 양을 확인할 수 있습니다.

    그리고 list 의 사이즈가 커질수록 메모리 할당량은 늘어나죠.

    반면, yield 에 의한 generator 는 반복문을 활용하는 구조이기 때문에 모든 값들이 메모리에 로드되지 않습니다.

    Caller Function 이 generator 를 호출할 때마다 다음 값을 계산하는 구조이기에

    연산을 좀 더 수행할 뿐이지 메모리를 크게 사용하지 않습니다.

    즉, CPU 연산과 메모리 용량에 대한 Trade-Off 가 존재하는 셈이죠.

     

    반응형
Designed by Tistory.