Generator (제너레이터)
제너레이터는 일련의 값을 생성하는 이터레이터의 일종으로, 함수처럼 정의되지만 값을 반환할 때 return 대신 yield 키워드를 사용합니다.
- 제너레이터는 지연 평가(Lazy Evaluation)를 통해 필요한 시점에 값을 생성합니다.
- 지연 평가: 필요한 시점에 값을 생성하여 메모리 효율성을 높입니다.
- 상태 유지: 마지막 실행 지점에서 멈추고 상태를 기억하여 다음 호출 시 그 지점부터 재개합니다.
- 메모리 효율성: 한 번에 하나의 값만 생성하므로 메모리 사용을 최소화합니다.
- 코드 간결화: 복잡한 이터레이터 코드를 간단히 작성할 수 있습니다.
def my_generator():
yield 1
yield 2
yield 3
yield 4
for item in my_generator():
print(item)
1
2
3
4
Iterator (이터레이터)
Iterator(이터레이터)는 __iter__() 와 __next__() 메서드를 구현한 객체입니다.
Iterator(이터레이터)는 반복 가능한 객체에서 값을 순차적으로 꺼내는 역할을 합니다.
- 상태 유지: 이터레이터는 현재 위치를 기억하여 next() 호출 시 다음 값을 반환합니다.
Iterator(이터레이터) 구현 예시
- 이터레이터를 직접 구현하려면 두 가지 메서드를 정의해야 합니다: __iter__()와 __next__().
class MyIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index < len(self.data):
result = self.data[self.index]
self.index += 1
return result
else:
raise StopIteration
my_iter = MyIterator([1, 2, 3, 4])
for item in my_iter:
print(item)
1
2
3
4
Generator (제너레이터) & Iterator (이터레이터) 차이점
1. 구현방식
- Iterator(이터레이터): Class(클래스) 형태로 __iter__()와 __next__() Method를 구현합니다.
- Generator(제너레이터): Function(함수) 형태로 yield 키워드를 사용합니다.
2. 사용 용의성
- Iterator(이터레이터): 상대적으로 복잡한 구조입니다.
- Generator(제너레이터): 간단한 코드로 구현 가능합니다.
3. 메모리 효율성
- Iterator(이터레이터): 모든 값을 메모리에 저장합니다.
- Generator(제너레이터): 값을 필요할 때마다 생성합니다.
Yield 키워드
yield 키워드는 Generator(제너레이터) 함수에서 값을 반환하고 함수의 실행 상태를 일시 중지하는 역할을 합니다.
- 이는 return 키워드와 유사하지만, 함수를 종료하지 않고 실행 상태를 저장합니다.
- 지연 평가: yield 키워드를 만나면 값을 반환하고 함수의 실행 상태를 저장합니다.
- 상태 유지: 다음 호출 시 저장된 상태에서 다시 시작합니다.
필요성
메모리 절약
- Generator(제너레이터)는 한 번에 하나의 값만 생성하므로 메모리 사용을 최소화할 수 있습니다.
def large_range():
for i in range(1_000_000):
yield i
# 메모리를 절약하면서 순차적으로 값을 생성
for value in large_range():
if value > 10:
break
print(value)
복잡한 흐름 제어
- 제너레이터를 사용하면 복잡한 반복 작업을 간단히 구현할 수 있습니다. 상태를 유지하면서 여러 단계의 작업을 처리할 수 있습니다.
def countdown(n):
while n > 0:
yield n
n -= 1
for number in countdown(5):
print(number)
Yield 키워드 활용 예시
대량 데이터 처리
def read_large_file(file_path):
with open(file_path, 'r') as file:
for line in file:
yield line
for line in read_large_file('large_file.txt'):
process(line)
대규모 데이터베이스 쿼리 결과 처리
def query_database(query):
cursor = connection.execute(query)
for row in cursor:
yield row
for row in query_database('SELECT * FROM large_table'):
process(row)
스트리밍 데이터 처리
실시간 데이터 스트리밍에서 제너레이터는 매우 유용합니다. 실시간 로그 파일을 처리할 때 사용할 수 있습니다.
def tail_file(file_path):
with open(file_path, 'r') as file:
file.seek(0, 2) # 파일의 끝으로 이동
while True:
line = file.readline()
if not line:
time.sleep(0.1) # 파일에 새로운 내용이 추가될 때까지 대기
continue
yield line
for line in tail_file('log.txt'):
print(line)
'⌨️ Python & Algorithm' 카테고리의 다른 글
[Python] Database - 데이터베이스 (0) | 2024.07.15 |
---|---|
[Python] 파일 입출력 (0) | 2024.07.15 |
[Python] Class & OOP (클래스 & 객체지향 프로그래밍) (0) | 2024.07.14 |
[Python] Python - Function (함수) (0) | 2024.07.14 |
[Python] Python - 변수와 자료형, 연산, 조건, 반복문 (0) | 2024.07.14 |