'Better way 33. yield from을 사용해 여러 제너레이터를 합성하라' 정리
Series -
Contents
들어가며
Effective Python 2nd 파이썬 코딩의 기술 (교보문고 링크)을 제대로 이해하고자 블로그에 정리합니다.
현재 위치
Note
<4. Comprehensions and Generators>
Item 33: Compose Multiple Generators with
Better way 33. yield from을 사용해 여러 제너레이터를 합성하라
Item 33: Compose Multiple Generators with
yield from
Better way 33. yield from을 사용해 여러 제너레이터를 합성하라
한 줄 요약 및 첨언
제너레이터가 제너레이터를 내포할 때는 yield from
으로 내포된 제네레이터에서 값을 바로 내보냅시다.
사용 예시
제너레이터를 사용해 한 루프마다 이미지의 변위를 만들어 내는 동작이 필요한 상황입니다.
def move(period, speed):
for _ in range(period):
yield speed
def pause(delay):
for _ in range(delay):
yield 0
def render(delta):
print(f'Delta: {delta:.1f}')
# Move the images onscreen
def run(func):
for delta in func():
render(delta)
# Example 4 (yield from 사용)
def animate_composed():
yield from move(4, 5.0)
yield from pause(3)
yield from move(2, 3.0)
run(animate_composed)
Delta: 5.0
Delta: 5.0
Delta: 5.0
Delta: 5.0
Delta: 0.0
Delta: 0.0
Delta: 0.0
Delta: 3.0
Delta: 3.0
기억해야 할 내용
책에서 챕터 마지막 부분에 적혀있는 내용입니다.
Tip
The
yield from
expression allows you to compose multiple nested generators together into a single combined generator.yield from
식을 사용하면 여러 내장 제너레이터를 모아서 제너레이터 하나로 합성할 수 있다.Tip
yield from
provides better performance than manually iterating nested generators and yielding their outputs.직접 내포된 제너레이터를 이터레이션하면서 각 제너레이터의 출력을 내보내는 것보다 yield from을 사용하는 것이 성능 면에서 더 좋다.
yield from 성능 비교
tileit 내장 모듈을 사용한 벤치마크
# Example 5
import timeit
def child():
for i in range(1_000_000):
yield i
# yield from 사용하지 않은 구현
def slow():
for i in child():
yield i
# yield from 사용한 구현
def fast():
yield from child()
baseline = timeit.timeit(
stmt='for _ in slow(): pass',
globals=globals(),
number=50)
print(f'Manual nesting {baseline:.2f}s')
comparison = timeit.timeit(
stmt='for _ in fast(): pass',
globals=globals(),
number=50)
print(f'Composed nesting {comparison:.2f}s')
reduction = -(comparison - baseline) / baseline
print(f'{reduction:.1%} less time')
Manual nesting 6.00s
Composed nesting 5.11s
14.8% less time