[python] 이터레이터 사용하기

anjiyoo·2024년 3월 8일

Python

목록 보기
37/41
post-thumbnail

1.이터레이터

  • 값을 차례대로 꺼낼 수 있는 객체
  • 데이터가 많을 때 메모리를 많이 사용하게 되어 성능이 안좋아짐
  • 파이썬은 이터레이터만 생성하고 값이 필요한 시점에 값을 만듦

🔥 지연평가 : 데이터 생성을 뒤로 미루는 방식


1-1.반복 가능한 객체

  • 요소개 여러 개 들어있고 한번에 하나씩 꺼낼 수 있는 객체
  • 문자열, 리스트, 튜플, range, 딕셔너리, 세트 등
이터레이터 = 반복가능한객체.__iter__()  # 반복 가능한 객체에서 이터레이터를 얻음
이터레이터.__next__()  # 반복 가능한 객체의 요소를 차례대로 꺼냄

이터레이터 = iter(반복가능한객체)  # iter 함수 사용
next(이터레이터)  # next 함수 사용
# 객체가 반복 가능한 객체인지 알아보는 함수
dir(객체)  # 객체에 __iter__ 메소드가 있는지 확인
it = [1,2,3,].__iter__()  # StopIteration 예외 발생
it.__next__()  # 요소를 계속 꺼내다가 꺼낼 요소가 없으면 예외 발생시켜 반복 끝냄

1-2.for와 반복 가능한 객체

for i in range(3):  # range를 통해 __iter__()를 얻고
	print(i)   # __next__()로 숫자를 꺼내서 i에 저장

시퀀스 객체 vs 반복 가능한 객체

  • 시퀀스 객체 : 리스트, 튜플, range, 문자열, 딕셔너리, 세트
  • 반복 가능한 객체 : 시퀀스 객체(리스트, 튜플, range, 문자열), map

2.이터레이터 만들기

  • __init__ 메소드에서 초깃값, __next__ 메소드에서 조건식과 현재값 부분 주의
class 이터레이터이름:
	def __iter__(self):
    	return self
        
    def __next__(self):
    	값 생성 코드, 반복을 끝내려면 StopIteration 예외를 발생시킴
        
이터레이터객체 = 이터레이터()  # 이터레이터 객체 생성
이터레이터.__next__()  # 이터레이터에서 값을 차례대로 꺼냄
next(이터레이터)  # next 함수 사용

foi i in 이터레이터():  # 이터레이터를 반복문에 사용
	pass
class 이터레이터이름:
	def __iter__(self):
    	코드
    def __next__(self):
    	코드
# range처럼 동작하는 이터레이터
class Counter:
	def __init__(self, stop):
    	self.current = 0   # 현재 숫자 유지, 0부터 지정된 숫자 직전까지 반복
       	self.stop = stop  # 반복을 끝낼 숫자
     
    def __iter__(self):
    	return self  # 반복 가능 객체가 없으므로 현재 인스턴스를 반환
        
    def __nect__(self):
    	if self.current < self.stop:  # 현재 숫자가 반복을 끝낼 숫자보다 작을 때
        	r = self.current  # 반환할 숫자를 변수에 저장
            self.current += 1  # 현재 숫자를 1 증가시킴
            return r  # 숫자를 반환
        else:  # 현재 숫자가 반복을 끝낼 숫자보다 크거나 같을 때
        	raise StopIteraion  # 예외발생
       
for i in Counter(3):
	pirnt(i, end= '')

2-1.이터레이터 언패킹

변수1, 변수2, 변수3 = 이터레이터()
반복하는 횟수와 변수의 개수는 같아야 함
a,b,c = Counter(3)
print(a,b,c)

3.인덱스로 접근할 수 있는 이터레이터 만들기

class 이터레이터이름:
	def __getitem__(self, 인덱스):
    	코드
# __getitem__메소드를 구현해 인덱스로 접근할 수 있는 이터레이터 만들기
class 이터레이터이름:
	def __getitem__(self, index):
    	인덱스에 해당하는 값을 반환하는 코드, 지정된 범위를 벗어났다면 IndexError 예외 발생

이터레이터객체 = 이터레이터()  # 이터레이터 객체 생성
이터레이터객체(인덱스)
class Counter:
	def __init__(self, stop):  # 초깃값이 없다면 __init__ 생략 가능
    	self.stop = stop  # 반복을 끝낼 숫자
    
    def __getitem__(self, index):  # 인덱스를 받음
    	if index < self.stop:  # 인덱스가 반복을 끝낼 숫자보다 작을 때
        	return index  # 인덱스 반환
        else:  # 인덱스가 반복을 끝낼 숫자보다 크거나 같을 때
        	raise IndexError  # 예외 발생
    
print(Counter(3)[0], Counter(3)[1], Counter(3)[2])

for i in Counter(3):
	print(i, end= '')

4.iter, next 함수 활용하기

  • iter : 객체의 __iter__ 메소드 호출
  • next : 객체의 __next__ 메소드 호출

4-1.iter

  • 반복을 끝낼 값(sentinel)을 지정하면 특정 값이 나올 때 반복을 끝냄
  • 반복 가능한 객체 대신 호출 가능한 객체를 넣어줌
iter(호출가능한객체, 반복을끝낼값)
import random
it = iter(lambda : random.radient(0,5),2)  # 호출 가능한 객체로 람다 표현식
next(it)  # 숫자를 계속 만들다가 2가 나오면 StopIteration 발생

4-2.next

  • 기본값을 지정할 수 있음
  • 기본값을 지정하면 반복이 끝나더라도 StopIteration이 발생하지 않고 기본값 출력
next(반복가능한객체, 기본값)
import random
it = iter(range(3)  # range로 반복. 반복이 끝난 뒤에도 next를 호출하면
                    # 예외가 발생하지 않고 계속 10이 나옴
next(it, 10)  # 기본값으로 10 지정
profile
기록으로 흔적을 남기는 것을 좋아합니다

0개의 댓글