[Python] 이터레이터 (iterator)

손종일·2020년 8월 23일
1

Python

목록 보기
3/13
post-thumbnail

이터레이터 (iterator)

이터레이터(iterator) or 반복자는 값을 차례대로 꺼낼 수 있는 객체(object)입니다.
(반복 가능한 객체)

이터레이터를 사용하는 이유는?

만약 연속된 숫자를 미리 만들면 숫자가 적을 때는 상관없지만 숫자가 아주 많을 때는 메모리를 많이 사용하게 되므로 성능에도 불리합니다. 그래서 파이썬에서는 이터레이터만 생성하고 값이 필요한 시점이 되었을 때 값을 만드는 방식을 사용합니다. 즉, 데이터 생성을 뒤로 미루는 것인데 이런 방식을 지연 평가(lazy evaluation)라고 합니다.

반복 가능한 객체인지 확인하는 방법

  • 즉, iter함수의 존재 여부로 반복가능한 객체인지 확인 할 수 있다.
li = [1, 2, 3]
print(dir(li)) 
	# ['__add__', '__class__', '__contains__', '__delattr__',
    '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', 
    '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__',
    '__iadd__', '__imul__', '__init__', '__init_subclass__', 
    '__iter__',  <== iter 함수가 있는지 확인.
    '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__',
    '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', 
    '__rmul__',      '__setattr__', '__setitem__', '__sizeof__',
    '__str__', '__subclasshook__', 'append', 'clear', 'copy', 
    'count', 'extend',  'index', 'insert', 'pop', 'remove', 
    'reverse', 'sort']

__iter__ 함수는 이터레이터 객체이며, 안을 뜯어보면 __next__ 함수가 존재하는것을 확인 할 수 있다.

li = [1, 2, 3]
iter_li = li.__iter()
print(dir(iter_li))
	#['__class__', '__delattr__', '__dir__', '__doc__', '__eq__',
        '__format__', '__ge__', '__getattribute__', '__gt__',
        '__hash__', '__init__', '__init_subclass__', '__iter__',
        '__le__', '__length_hint__', '__lt__', '__ne__', '__new__',
        '__next__',		# < == __next__ 함수 포함
        '__reduce__', '__reduce_ex__', '__repr__',
        '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

또한 리스트의 이터레이터를 변수에 저장한 뒤 __next__ 메소드를 사용하여 하나씩 호출

li = [1, 2, 3]
iter_li = li.__iter__()
-
print(iter_li)		       # <list_iterator object at 0x7ff2da82ff70>
print(iter_li.__next__())	# 1
print(iter_li.__next__())	# 2
print(iter_li.__next__())	# 3
print(iter_li.__next__())	# StopIteration
'Hello, world!'.__iter__()			#__next__ 호출시 H, e,~, !
<str_iterator object at 0x03616770>
{'a': 1, 'b': 2}.__iter__()			#__next__ 호출시 'a', 'b'
<dict_keyiterator object at 0x03870B10>
{1, 2, 3}.__iter__()				#__next__ 호출시 1, 2, 3
<set_iterator object at 0x03878418>

이번에는 요소가 눈에 보이지 않는 range를 살펴보겠습니다. 다음과 같이 range(3)에서 iter로 이터레이터를 얻어낸 뒤 next 메서드를 호출해봅니다. 즉, range(3)이므로 0, 1, 2 세 번 반복하며 요소가 눈에 보이지 않지만 지정된 만큼 숫자를 꺼내서 반복할 수 있습니다.

it = range(3).__iter__()
it.__next__()		# 1
it.__next__()		# 2
it.__next__()		# 3
it.__next__()		# StopIteration

정리하자면 반복 가능한 객체는 요소를 한 번에 하나씩 가져올 수 있는 객체이고, 이터레이터는 __next__메서드를 사용해서 차례대로 값을 꺼낼 수 있는 객체입니다.

여기서 문제! 아래의 for 문을 사용하여 dictionary 의 키 값을 출력하였습니다. 해당 키 값을 while 문을 사용하여 출력하세요.

# for key in D.keys():
#     print(key)
# print(D.keys([0])) 	# a
			# b
            		# c
D = {'a':1, 'b':2, 'c':3}

it = iter(D)

n=1
while True :
    try:
        print(next(it))
    except StopIteration:
        print("ERROR")
        break		# a
        		# b
                	# c
                    	# ERROR
profile
Allday

0개의 댓글