Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python 개선 제안 한국어 번역

PEP 3142 – 제너레이터 표현식에 “while” 절 추가

Author:
Gerald Britton <gerald.britton at gmail.com>
Status:
Rejected
Type:
Standards Track
Created:
12-Jan-2009
Python-Version:
3.0
Post-History:

Resolution:
Python-Dev message

Table of Contents

번역·라이선스 안내

이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판

초록

이 PEP는 제너레이터 표현식을 개선하여 기존의 “if” 절을 보완하는 “while” 절을 추가할 것을 제안합니다.

근거

제너레이터 표현식(PEP 289)은 동적으로 생성된 객체를 리스트 컴프리헨션(PEP 202)에 제공하는 간결한 방법입니다. 현재 제너레이터 표현식에서는 “if” 절을 사용하여 특정 기준을 충족하는 객체만 반환되도록 필터링할 수 있습니다. 그러나 반환될 수 있는 모든 객체에 대해 “if” 절이 평가되므로, 경우에 따라 특정 시점 이후의 모든 객체가 거부될 수 있습니다. 예를 들어:

g = (n for n in range(100) if n*n < 50)

이는 제너레이터 함수(PEP 255)를 사용하는 것과 같습니다.:

def __gen(exp):
    for n in exp:
        if n*n < 50:
            yield n
g = __gen(iter(range(10)))

0, 1, 2, 3, 4, 5, 6, 7을 생성하지만, 8부터 99까지의 숫자도 확인하고 해당 범위의 숫자에서는 n*n >= 50이므로 모두 거부합니다. “while” 절을 허용하면 불필요한 검사를 조기에 중단할 수 있습니다.:

g = (n for n in range(100) while n*n < 50)

마찬가지로 0, 1, 2, 3, 4, 5, 6, 7을 생성하지만, 조건(n*n < 50)이 더 이상 참이 아니므로 8에서 중단합니다. 이는 다음 제너레이터 함수와 같습니다.:

def __gen(exp):
    for n in exp:
        if n*n < 50:
            yield n
        else:
            break
g = __gen(iter(range(100)))

현재 동일한 결과를 얻으려면 위와 같은 제너레이터 함수를 작성하거나 itertools의 takewhile 함수를 사용해야 합니다.:

from itertools import takewhile
g = takewhile(lambda n: n*n < 50, range(100))

takewhile 코드는 제안된 구문과 동일한 결과를 더 긴 방식(일부는 “덜 우아한” 방식이라고 할 수 있습니다)으로 얻습니다. 또한 takewhile 버전은 그에 따른 성능 저하와 함께 추가 함수 호출(위 예제의 lambda)을 필요로 합니다. 간단한 테스트를 수행하면 다음과 같은 결과가 나옵니다.:

for n in (n for n in range(100) if 1): pass

다음보다 약 10% 더 나은 성능을 보입니다.:

for n in takewhile(lambda n: 1, range(100)): pass

두 방식은 비슷한 결과를 얻습니다. (첫 번째 예제는 제너레이터를 사용하고, takewhile은 이터레이터입니다.) 같은 방식으로 구현한다면 “while” 절은 현재의 “if” 절과 거의 동일한 성능을 보여야 합니다.

독자는 “if” 절과 “while” 절을 상호 배타적으로 만들어야 하는지 질문할 수 있습니다. 두 절을 모두 사용하면 유용한 경우가 있음을 보여 주는 좋은 예가 있습니다. 예를 들어:

p = (p for p in primes() if p > 100 while p < 1000)

100에서 1000 사이에서 발견되는 소수를 반환해야 하며, primes() 제너레이터가 소수를 생성한다고 가정합니다.

제너레이터 표현식에 “while” 절을 추가하면 간결한 형식을 유지하면서 표현식을 조기에 중단할 수 있는 유용한 기능을 추가합니다.

감사의 말

Raymond Hettinger는 2002년 1월에 제너레이터 표현식의 개념을 처음 제안했습니다.