| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- TTS
- 데이터엔지니어
- 에이전트
- 힙정렬
- dementional reduction
- 캐글
- 트랜스포머
- 딥러닝
- 알고리즘
- SQL
- 정보처리기사
- ASR
- Python
- 생성형 인공지능
- CNN
- 객체지향
- RNN
- python 기초
- LangGraph
- UMAP
- RDBMS
- 머신러닝
- CLIP
- 기초
- 랭그래프
- 소프트웨어 개발
- 데이터 시각화
- python기초
- Transformer
- 자연어처리
- Today
- Total
수달이네 기술 블로그
16. 이터레이터, 제너레이터 본문
이전에 range()를 사용할 때 리스트가 아닌 제너레이터를 반환한다고 배운적이 있다.
이번엔 이터레이터와 제너레이터등의 반복문에서 주로 사용하는 객체를 배웠다.
🔍이터레이터(반복 가능한 객체)
반복가능한 객체란: list, tuple, range, dictionary, set등의 for루프와 함께 사용할 수 있는 것
- x = [1,2,3] → __iter__ → iterator객체 → __next__ → 내용이 없을 경우 StopIteration예외를 반환한다.
__iter__(): 반복 가능한 객체 자신을 반환한다.
__next__(): 다음 반복을 위한 값을 반환한다. 내용이 없을 경우 StopIteration예외를 발생시킨다.
class MyCounter(object):
def __init__(self, low, high):
self.current = low
self.high = high
# 이터레이터 객체로서 자신을 반환한다.
def __iter__(self):
return self
def __next__(self):
# current가 high 보다 크면 StopIteration예외처리.
# current가 high 보다 높으면 다음값을 반환한다.
if self.current > self.high:
raise StopIteration
else:
self.current += 1
#self.current가 1을 증가했으나, 이전값을 출력하기 위해 리턴
return self.current - 1
c = MyCounter(1,10)
for x in c:
print(x, end = " ")
#1 2 3 4 5 6 7 8 9 10
raise: 강제로 예외를 발생시킴
위의 코드를 보면 class에 __iter__()와 __next__()메서드를 구현해줌으로써 iterator로서의 기능을 할 수 있게 되었다.
그러면 반복문에 넣어 다음 내용을 부를 때 자동으로 next()함수가 불러와져 다음 객체를 넘기고,
만약 정해둔 high보다 커질 경우 StopIteration예외를 불러온다.
test = [10,20]
test_iter = iter(test)
test_next = next(test_iter)
print(test_next)
test_next = next(test_iter)
print(test_next)
test_next = next(test_iter)
print(test_next)
# 10
# 20
# Traceback (most recent call last):
# File "C:", line 7, in <module>
# test_next = next(test_iter)
# StopIteration
아래는 함수 없이 iter함수와 next함수의 기능을 보인 함수이다.
리스트를 iter()객체로 만든 후 next로 다음 값을 끌어온다.
범위를 벗어나면 StopIteration오류가 일어나는 것도 확인 가능하다.
🔍제너레이터
파이썬 2.3버전부터 도입된 객체로 yield키워드를 이용하여 함수로부터 반복가능한 객체를 생성한다.
def myGenerator():
yield 'first'
yield 'second'
yield 'third'
for word in myGenerator():
print(word)
# first
# second
# third
원래는 함수는 반복 불가능한 객체이나 반복 가능하게 만들어주는 yield객체가 생겼다.
def MyCounterGen(low, high):
while low <= high:
yield low
low += 1
for i in MyCounterGen(1,10):
print(i, end=' ')
#1 2 3 4 5 6 7 8 9 10
여기서 보면 yield 가 나오면 대기상태로 들어가 결과를 일단 반환한 후, 다음 코드를 실행시킨다.
def MyCounterGen(low, high):
while low <= high:
yield low
low += 1
print("func")
for i in MyCounterGen(1,5):
print(i, end=' ')
# 1 func
# 2 func
# 3 func
# 4 func
# 5 func
아래를 보면 yield다음 func가 출력되야 하는데 함수를 나와 숫자를 출력한다.
위처럼 함수 밖으로 나가 내용을 출력시킨다.
yield 와 yield from 의 차이
import time
def gen():
list1 = [10,20,30]
yield list1
time.sleep(1)
print("gen()내의 list값", list1)
if __name__ == '__main__':
test_gen = gen()
n = next(test_gen)
print("main()내의 list값", n)
#main()내의 list값 [10, 20, 30]
yield를 사용할 경우 list값 전체를 내보냈다.
만약 여기서 next를 한번 더 사용할 경우 리스트 객체 하나를 이미 내보냈으므로 다음 객체에서는 StopIteration오류가 날 것이다.
import time
def gen():
list1 = [10,20,30]
yield from list1
time.sleep(1)
print("gen()내의 list값", list1)
if __name__ == '__main__':
test_gen = gen()
n = next(test_gen)
print("main()내의 list값", n)
n = next(test_gen)
print("main()내의 list값", n)
# main()내의 list값 10
# main()내의 list값 20
yield from을 사용하면 리스트를 반환하지만 리스트의 요소값을 하나씩 꺼내서 보여준다.
그렇기 때문에 next()가 한번더 불리더라도 아직 값이 남아있으므로 print("gen()내의 list값", list1) 해당 구문이 출력되지 않았다.
반환한 리스트를 전부 다 소진할 때 까지는 함수내의 다음 라인이 출력되지 않을 것이다.
🔍이터레이터 vs 제너레이터
이터레이터는 모든 동작을 완료한 후 결과를 한번에 메모리에 적재시키지만,
제너레이터는 각각의 yield를 실행시킨후 대기상태에 들어가 반호나하기를 반복하는 방식이다.
'언어 > Python' 카테고리의 다른 글
| 2. 파이썬에서의 상속 (0) | 2025.11.05 |
|---|---|
| 17. 스레드 (0) | 2025.09.04 |
| 15. 함수3(내장 함수, 정렬, 람다식...) (1) | 2025.09.02 |
| 14. 파일, 예외처리(파일 읽기, 쓰기, 인코딩... ,exception handling) (7) | 2025.09.01 |
| 13. 객체지향2(다중상속, 다형성, 추상클래스...) (2) | 2025.08.31 |