Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬 제너레이터로 반복자 만들기: yield 키워드부터 커스텀 이터레이터까지

네, 가능합니다. 파이썬에서는 제너레이터(generator)를 사용해 반복자(iterator)를 손쉽게 만들 수 있습니다. 제너레이터는 yield 키워드만 사용하면 되기 때문에 반복자 생성 방법 중 가장 간단하고 직관적인 방식으로 꼽힙니다.

파이썬 제너레이터는 반복자를 만드는 쉽고 간결한 방법으로, 주로 이터레이터처럼 동작하는 함수를 선언할 때 사용됩니다. 일반적인 함수와 달리 모든 값을 한 번에 반환하지 않고, 호출될 때마다 값을 하나씩 순차적으로 생성해 반환한다는 점이 특징입니다.

실제 개발 현장에서 프로그래머들은 리스트(list), 문자열(string), 딕셔너리(dict) 같은 순회 가능한(iterable) 객체를 매우 자주 다룹니다. 여기서 반복자(iterator)란 for 루프 등을 통해 요소를 하나씩 순회할 수 있는 객체를 의미합니다.

다음 예제는 파이썬에서 yield 문을 사용한 제너레이터의 기본 동작을 보여줍니다. yield는 값을 반환하는 것처럼 보이지만, 함수 실행을 잠시 멈춘 뒤 다음 호출 시 중단된 지점부터 이어서 실행된다는 점에서 return과 다릅니다.

예제 1: yield로 제너레이터 만들기

def generator():
    print("program working sucessfully")
    yield 'x'
    yield 'y'
    yield 'z'

generator()

출력 결과

<generator object generator at 0x000000CF81D07390>

함수를 단순히 호출하면 위 출력처럼 제너레이터 객체만 반환될 뿐, 함수 본문은 아직 실행되지 않습니다. 제너레이터의 내용을 실제로 확인하려면 for 루프를 사용하거나 next() 함수를 호출해야 합니다.

예제 2: for 루프로 제너레이터 순회하기

for i in generator():
    print(i)

출력 결과

program working sucessfully
x
y
z

반복자 프로토콜: __iter__와 __next__

반복자 객체는 두 가지 핵심 메서드를 지원합니다.

  • __iter__ 메서드: 반복자 객체 자신(self)을 반환합니다. 주로 for 루프나 in 연산자 내부에서 사용됩니다.
  • __next__ 메서드: 반복자에서 다음 값을 반환합니다. 더 이상 반환할 값이 없으면 StopIteration 예외를 발생시켜야 합니다.

아래 예제는 이 두 메서드를 직접 구현하여, 지정한 온도 범위를 순회하는 커스텀 반복자 클래스를 만든 것입니다.

예제 3: 클래스로 반복자 직접 구현하기

class function(object):
    def __init__(self, lowtemp, hightemp):
        self.current = lowtemp
        self.high = hightemp

    def __iter__(self):
        'Returns itself as an iterator object'
        return self

    def __next__(self):
        'Returns the next value till current is lower than high'
        if self.current > self.high:
            raise StopIteration
        else:
            self.current += 1
            return self.current - 1

c = function(3, 20)
for i in c:
    print(i, end=' ')

출력 결과

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

이처럼 yield 키워드를 활용한 제너레이터는 코드를 훨씬 간결하게 만들어 줄 뿐 아니라, 값을 필요할 때마다 하나씩 생성하기 때문에 대용량 데이터를 처리할 때 메모리 효율성 면에서도 큰 장점을 제공합니다. 클래스로 반복자를 직접 구현하는 방식과 비교했을 때, 제너레이터가 훨씬 적은 코드로 동일한 기능을 구현할 수 있다는 점도 눈여겨볼 만합니다.