Python - iterable 과 iterator, 그리고 반복문
iterable 의 정의 및 이해
iterable : 한 번에 하나의 member를 반환할 수 있는 object (객체)를 의미.
iterator 로 변환이 가능.
- list, str, tuple 와 같은 모든 Sequence type
- dict, file object 혹은 sequence semantic 을 가진 __iter__() method 나 __getitem__() method 가 구현된 object
iterable 은 for loop 나 sequence 가 필요한 zip(), map() 등에 사용될 수 있다.
일반적으로 iterator 로 변환 후 사용된다.
iter() 를 이용해 해당 object의 iterator를 생성하여 사용할 수도 있지만, for 와 같은 statement에서는 자동으로 임의의 iterator를 생성하여 사용된다.
class oneDigitList_iterable:
# Class to implement an iterable of oneDigitCount
def __init__(self, max = 10):
if max >= 10:
self.max = 10
else:
self.max = max
self.n = 1
def __iter__(self):
while self.n < self.max:
yield self.n
self.n += 1
oneList = oneDigitList_iterable()
print(oneList)
print(type(oneList))
for item in oneList:
print(item)
user@TechNote:~$ python3 iterable.py
<__main__.oneDigitList object at 0x7fdb1847b748>
<class '__main__.oneDigitList'>
1
2
3
4
5
6
7
8
9
위의 경우 oneDigitList instance 내에 __iter__() method 가 구현되어 있어 iterable 하다.
하지만 iterable 한 상태로 바로 사용되지 않고, for ~ in 구문과 같이 사용되어 자동으로 iterator 로 변환 후 사용되었다.
iterator 의 정의 및 이해
iterator : 데이터의 흐름 (stream)을 의미.
흐름 (stream) 내에서 바로 다음에 처리해야 할 데이터를 기억하고 있음.
iterator 는 iterator object 를 반환하기 위해 __iter__() method 또한 필요로 하고, 이로인해 iterable 이 사용되는 곳에서도 사용 가능하다.
class oneDigitList_iterator:
# Class to implement an iterator of oneDigitCount
def __init__(self, max = 10):
if max >= 10:
self.max = 10
else:
self.max = max
self.n = 1
def __iter__(self):
return self
def __next__(self):
while self.n < self.max:
self.n += 1
return self.n - 1
else:
raise StopIteration
oneList = oneDigitList_iterator()
print(oneList)
print(type(oneList))
for item in oneList:
print(item)
user@TechNote:~$ python3 iterator.py
<__main__.oneDigitList_iterator object at 0x7f79f6817630>
<class '__main__.oneDigitList_iterator'>
1
2
3
4
5
6
7
8
9
__next__() method 를 호출할 때 마다 해당 stream 내의 연속적인 아이템을 반환한다. 해당 흐름 내에 더 이상 반환할 아이템이 없을 경우 StopIteration exception 을 발생시킨다.
iterableList = [1, 2, 3]
iterator = iter(iterableList)
print(next(iterator))
print(next(iterator))
print(next(iterator))
print(next(iterator))
user@TechNote:~$ python3 iterator_2.py
1
2
3
Traceback (most recent call last):
File "iterator_2.py", line 7, in <module>
print(next(iterator))
StopIteration
list 와 같은 container 를 iter() function에 넘기거나 for loop 에서 사용하게 되면 매번 새로운 iterator 를 생성한다.
아래와 같이 iterator 를 만든 후 해당 iterator 를 사용하게 되면 이미 위치가 끝을 가리킨 이후에는 아무런 데이터를 반환하지 않는다.
iterableList = [1, 2, 3]
print("Based on List(iterable)")
for item in iterableList:
print(item)
for item in iterableList:
print(item)
iterator = iter(iterableList)
print("Based on iterator")
for item in iterator:
print(item)
for item in iterator:
print(item)
user@TechNote:~$ python3 iterator_3.py
Based on List(iterable)
1
2
3
1
2
3
Based on iterator
1
2
3