유튜브 강의와 GPT로 정리하였습니다.
출처: 유튜브 - Generators - Advanced Python Tutorial #3
일반적인 함수는 호출되면 모든 코드를 한 번에 실행하고 끝난다.
하지만 Generator 함수는 yield를 사용하여 실행을 중간에 멈추고, 다시 호출하면 멈춘 지점부터 실행을 이어갈 수 있음.
next()
를 호출하여 한 번에 하나의 값을 가져올 수 있음.def my_generator():
print("Start")
yield 1
print("Step 2")
yield 2
print("Step 3")
yield 3
print("End")
gen = my_generator() # Generator 객체 생성
print(next(gen)) # 첫 번째 yield 실행
print(next(gen)) # 두 번째 yield 실행
print(next(gen)) # 세 번째 yield 실행
print(next(gen))
Start
1
Step 2
2
Step 3
3
End
Traceback (most recent call last):
...
StopIteration
🔹 동작 설명
next(gen)
호출 → "Start" 출력 후 yield 1 실행 → 1 반환 후 멈춤.next(gen)
호출 → "Step 2" 출력 후 yield 2 실행 → 2 반환 후 멈춤.next(gen)
호출 → "Step 3" 출력 후 yield 3 실행 → 3 반환 후 멈춤.next(gen)
호출 → "End" 출력 후 더 이상 yield가 없으므로 StopIteration 예외 발생.✅ next()는 Generator를 한 단계 진행하여 yield 값을 반환하는 역할.
✅ Generator에 더 이상 yield 값이 없으면 StopIteration 예외가 발생.
def simple_gen():
yield "A"
yield "B"
yield "C"
gen = simple_gen()
print(next(gen)) # A
print(next(gen)) # B
print(next(gen)) # C
print(next(gen)) # StopIteration 발생
✅ 메모리 효율적
✅ 무한 시퀀스 처리 가능
def infinite_numbers():
num = 1
while True:
yield num
num += 1 # 계속 증가
gen = infinite_numbers()
print(next(gen)) # 1
print(next(gen)) # 2
print(next(gen)) # 3
=> 무한히 실행 가능
💡 리스트(range())를 사용하면 메모리가 한계에 도달하지만, Generator는 메모리 낭비 없이 값을 하나씩 생성 가능.
Python의 리스트 컴프리헨션(List Comprehension) 과 유사한 방식으로 Generator를 만들 수도 있음.
# 리스트 컴프리헨션 (메모리를 차지함)
lst = [x * 2 for x in range(10)]
print(lst) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
# Generator 표현식 (메모리 효율적)
gen = (x * 2 for x in range(10))
print(next(gen)) # 0
print(next(gen)) # 2
print(next(gen)) # 4
✅ 리스트 컴프리헨션은 모든 값을 한 번에 메모리에 저장하지만,
✅ Generator 표현식은 필요할 때만 값을 생성하여 메모리 사용량을 절약함.
여러 개의 Generator를 연결할 때 yield from을 사용하면 더 간결하게 코드 작성 가능.
def sub_generator():
yield 1
yield 2
yield 3
def main_generator():
yield from sub_generator() # sub_generator의 모든 값을 yield
yield 4
yield 5
gen = main_generator()
for value in gen:
print(value)
📌 실행 결과
1
2
3
4
5
✅ yield from을 사용하면 중첩된 Generator 값을 간단하게 반환 가능
✅ for 루프에서 직접 yield를 호출하지 않아도 모든 값을 자동으로 가져옴
💡 일반적으로 readlines()를 사용하면 전체 파일을 한 번에 읽어 메모리를 많이 차지하지만, Generator를 사용하면 한 줄씩 읽을 수 있어 메모리 절약 가능.
def read_large_file(filename):
with open(filename, "r") as file:
for line in file:
yield line.strip() # 한 줄씩 반환
for line in read_large_file("large_data.txt"):
print(line) # 한 줄씩 출력
✅ 파일 크기에 관계없이 한 줄씩 처리하여 메모리 낭비를 방지.
✅ yield를 사용하여 필요할 때마다 줄을 읽어오기 때문에 메모리 사용량이 일정.
개념 | 설명 |
---|---|
yield | Generator에서 상태를 유지하면서 값을 반환 |
next() | Generator의 다음 yield 까지 실행 |
yield from | 다른 Generator 또는 Iterable의 모든 값을 가져오기 |
Generator 표현식 | () 를 사용하여 메모리를 절약하면서 값 생성 |
✅ Generator는 리스트보다 메모리 효율적이며 필요할 때만 값을 생성
✅ next()
를 사용해 값을 하나씩 생성하면서 사용할 수 있음
✅ yield from
을 사용하면 중첩된 Generator를 간결하게 처리 가능
✅ 무한 루프(while True)나 대용량 데이터 처리에 최적화된 방식