def simple_generator():
yield 1
yield 2
yield 3
= simple_generator()
gen
print(next(gen)) # 출력: 1
print(next(gen)) # 출력: 2
print(next(gen)) # 출력: 3
1
2
3
yield
제너레이터와 효율적인 반복 처리파이썬 yield
제너레이터와 효율적인 반복 처리
yield
제너레이터와 효율적인 반복 처리
gabriel yang
October 1, 2024
yield
제너레이터와 효율적인 반복 처리파이썬에는 yield
라는 강력한 명령어가 있습니다. yield
는 함수에서 값을 반환하는 역할을 하지만, 함수의 실행을 종료하지 않고 중단하여 제너레이터(generator)를 생성합니다. 이 글에서는 yield
의 동작 방식, 이를 사용하는 이유, 그리고 제너레이터가 반복 처리를 효율적으로 수행하는 방법을 설명합니다.
yield
란?파이썬의 yield
는 함수를 제너레이터로 변환하는 키워드입니다. 일반적으로 함수는 return
키워드를 사용해 값을 반환하고 실행을 종료합니다. 그러나 yield
를 사용하면 함수가 값을 반환한 후에도 그 상태를 기억하고 다시 호출될 때 이전 상태부터 계속 실행됩니다.
yield
의 동작 방식:yield
를 만나면 값을 반환한 후 함수 실행을 일시 중지합니다.def simple_generator():
yield 1
yield 2
yield 3
gen = simple_generator()
print(next(gen)) # 출력: 1
print(next(gen)) # 출력: 2
print(next(gen)) # 출력: 3
1
2
3
위의 예에서 simple_generator
함수는 yield
를 사용하여 값을 반환합니다. 이 함수는 한 번에 하나의 값을 반환하며, 이후 호출될 때마다 중단된 지점부터 다시 실행됩니다.
yield
와 제너레이터yield
는 제너레이터를 생성하는 핵심 요소입니다. 제너레이터는 데이터를 미리 계산해 메모리에 저장하는 대신, 필요할 때마다 계산해서 반환합니다. 이 방식은 메모리를 효율적으로 사용하게 하고, 특히 대용량 데이터를 처리할 때 유용합니다.
yield
와 return
의 차이점return
은 값을 반환하고 함수의 실행을 종료합니다. 반면, yield
는 값을 반환하지만 함수 실행을 중단하고 상태를 기억한 채로 대기합니다. 즉, 제너레이터 함수는 호출될 때마다 값을 하나씩 차례로 반환하는 반복자(iterator)의 역할을 합니다.
def simple_return():
return 1
return 2 # 이 코드는 실행되지 않음
def simple_yield():
yield 1
yield 2
print(simple_return()) # 출력: 1
gen = simple_yield()
print(next(gen)) # 출력: 1
print(next(gen)) # 출력: 2
1
1
2
return
을 사용한 함수는 첫 번째 값을 반환하고 즉시 종료되지만, yield
를 사용한 함수는 중단된 지점에서 다시 실행됩니다.
제너레이터는 메모리를 효율적으로 사용하기 때문에, 대용량 데이터나 무한 시퀀스를 처리할 때 매우 유용합니다. 예를 들어, 10억 개의 숫자를 생성해야 한다면 리스트에 모든 값을 저장하는 것은 메모리 측면에서 비효율적입니다. 대신 제너레이터를 사용하면 하나씩 값을 생성하고 처리할 수 있습니다.
이 예시에서 large_range
함수는 무한에 가까운 숫자를 생성하지만, 메모리에는 하나의 값만 저장됩니다.
제너레이터는 필요할 때마다 값을 계산해 반환하기 때문에 지연 평가(Lazy Evaluation)를 수행합니다. 즉, 다음 값이 요청될 때까지 계산이 미뤄져 불필요한 작업을 방지할 수 있습니다.
위의 코드는 무한 루프를 실행하는 제너레이터로, 요청할 때마다 하나씩 값을 반환합니다. 제너레이터는 값을 미리 계산해두지 않으므로, 필요할 때마다 값을 생성합니다.
제너레이터는 다른 제너레이터와 결합하여 파이프라인 처리에도 사용할 수 있습니다. 데이터의 흐름을 제어하면서 각 단계에서 필요한 연산을 적용할 수 있습니다.
def generator1():
for i in range(5):
yield i
def generator2(gen):
for value in gen:
yield value * 2
gen = generator2(generator1())
print(list(gen)) # 출력: [0, 2, 4, 6, 8]
[0, 2, 4, 6, 8]
여기서 generator1
은 0부터 4까지의 숫자를 생성하고, generator2
는 이 값을 받아서 2배로 변환한 후 반환합니다.
yield
사용 시 주의할 점한 번만 반복 가능: 제너레이터는 한 번 실행되면 끝까지 진행됩니다. 다시 반복하려면 제너레이터를 새로 생성해야 합니다.
제너레이터 상태를 추적: 제너레이터는 상태를 유지하며 실행되기 때문에, 함수 내에서 값을 추적하고 관리해야 합니다. 이는 복잡한 로직을 구성할 때 유의해야 할 점입니다.
예외 처리: 제너레이터 안에서 예외가 발생하면 제너레이터가 종료됩니다. 따라서 제너레이터 내부에서도 적절한 예외 처리가 필요합니다.
파일을 한 줄씩 처리할 때 제너레이터를 사용하면 메모리 사용을 줄일 수 있습니다.
def read_file_line_by_line(file_path):
with open(file_path, 'r') as file:
for line in file:
yield line.strip()
# 파일에서 한 줄씩 읽기
for line in read_file_line_by_line('example.txt'):
print(line)
이 코드는 파일을 한 번에 전체 읽지 않고, 한 줄씩 처리합니다. 이는 매우 큰 파일을 처리할 때 유용합니다.
네트워크 요청을 비동기적으로 처리하면서 결과를 순차적으로 반환할 때도 제너레이터가 유용합니다.
파이썬의 yield
는 함수의 실행을 중단하고, 필요한 시점에서 값을 반환하는 강력한 도구입니다. 이를 통해 제너레이터를 만들면, 메모리를 절약하면서 대규모 데이터를 처리하거나, 무한 시퀀스를 효율적으로 다룰 수 있습니다. 특히 반복 작업이나 지연 평가가 필요한 상황에서 제너레이터와 yield
를 적절히 활용하면 성능과 코드 가독성을 모두 개선할 수 있습니다.
Date | Title | Author |
---|---|---|
Jan 1, 3000 | 전체 카테고리 | gabriel yang |
Nov 26, 2024 | VSCode에서 Python 디버깅 (launch.json 설정) | gabriel yang |
Nov 23, 2024 | Python 설치된 패키지 확인, 설치와 복원하기 | gabriel yang |
Oct 14, 2024 | JSON 파일에서 특정 key의 값 변경 후 저장하는 방법 | gabriel yang |
Oct 10, 2024 | 날짜 문자열을 날짜 형식으로 변환하기 | gabriel yang |
Oct 8, 2024 | Request를 통한 JIRA REST API 사용방법 | gabriel yang |
Oct 8, 2024 | Request 라이브러리 사용방법 | gabriel yang |
Oct 8, 2024 | Requests 라이브러리로 베이직 인증 API 호출하기 | gabriel yang |
Oct 7, 2024 | Python으로 SSH를 제어하기 | gabriel yang |
Oct 7, 2024 | Pytest로 테스트하기 | gabriel yang |
Oct 7, 2024 | Pytest 기본적인 테스트 실행 방법 | gabriel yang |
Oct 7, 2024 | Pytest Fixture 개념과 필요성 | gabriel yang |
Oct 7, 2024 | CI 환경에서 Pytest 사용하기 | gabriel yang |
Oct 7, 2024 | 파이썬에서 테스트 코드 리팩토링 기법 | gabriel yang |
Oct 5, 2024 | Python os 모듈을 이용한 파일과 폴더 관리 | gabriel yang |
Oct 5, 2024 | Python shutil 모듈을 이용한 파일과 폴더 관리 | gabriel yang |
Oct 5, 2024 | MongoDB 데이터베이스 백업 및 복원 방법 | gabriel yang |
Oct 5, 2024 | Python jira 라이브러리를 이용해 JIRA를 관리하는 방법 | gabriel yang |
Oct 4, 2024 | Python에서 JSON 파일 읽기 및 데이터 활용 | gabriel yang |
Oct 4, 2024 | JSON 데이터 수정하기 | gabriel yang |
Oct 4, 2024 | JSON 파일의 구성요소와 구조 | gabriel yang |
Oct 4, 2024 | Python에서 Git명령 사용하기 | gabriel yang |
Oct 3, 2024 | 파이썬으로 클래스 정의하는 방법 | gabriel yang |
Oct 3, 2024 | 파이썬의 상속(Inheritance) 이해하기 | gabriel yang |
Oct 3, 2024 | 파이썬 클래스의 self 이해하기 | gabriel yang |
Oct 3, 2024 | 파이썬에서 추상 클래스(Abstract Class) 사용하기 | gabriel yang |
Oct 3, 2024 | 파이썬 클래스 활용 예시 | gabriel yang |
Oct 3, 2024 | 파이썬 클래스와 모듈 | gabriel yang |
Oct 3, 2024 | 파이썬에서 Lock을 사용하는 이유와 방법 | gabriel yang |
Oct 2, 2024 | Python에서 zip()을 사용하는 이유와 방법 | gabriel yang |
Oct 2, 2024 | 파이썬 시퀀스 슬라이싱 | gabriel yang |
Oct 2, 2024 | 파이썬에서 Generator를 사용하는 이유와 사용법 | gabriel yang |
Oct 2, 2024 | 파이썬의 @property 기능 | gabriel yang |
Oct 2, 2024 | 파이썬 시퀀스 언패킹 | gabriel yang |
Oct 2, 2024 | 파이썬 데이터 정렬 | gabriel yang |
Oct 2, 2024 | 파이썬 딕셔너리 key 예외처리하기 | gabriel yang |
Oct 2, 2024 | 파이썬의 defaultdict 사용법 | gabriel yang |
Oct 2, 2024 | 파이썬의 try-except 사용법 | gabriel yang |
Oct 2, 2024 | 파이썬의 클로저(Clsure) 사용법 | gabriel yang |
Oct 2, 2024 | 파이썬의 가변인자 사용법 | gabriel yang |
Oct 2, 2024 | 파이썬의 컴프리헨션(Comprehension) 사용법 | gabriel yang |
Oct 1, 2024 | 파이썬 가상환경 설정 | gabriel yang |
Oct 1, 2024 | 파이썬을 이용한 테스트 자동화 | gabriel yang |
Oct 1, 2024 | 파이썬 docstring을 사용하는 이유와 방법 | gabriel yang |
Oct 1, 2024 | 파이썬 데이터 언패킹 | gabriel yang |
Oct 1, 2024 | Python에서 enumerate를 사용하는 이유와 사용 방법 | gabriel yang |
Sep 30, 2024 | Python 설치 및 기본 파이썬 버전 설정 | gabriel yang |
Sep 30, 2024 | Python을 이용한 폴더 전체 복사 방법 | gabriel yang |
Sep 30, 2024 | Public Key와 Private Key의 역할 | gabriel yang |
Sep 23, 2024 | Python의 @dataclass 데코레이터 | gabriel yang |
Aug 30, 2024 | Python shell명령 수행하기 (Subprocess) | gabriel yang |
Aug 29, 2024 | Google Colab에서 라이브러리 설치하기 | gabriel yang |
Aug 1, 2024 | 환경변수 설정하고 Python에서 읽어오기 | gabriel yang |
Jan 1, 2024 | 코루틴(coroutine)과 이벤트 루프 | gabriel yang |