Language/Python

Python - iterable 과 iterator, 그리고 반복문

TechNote.kr 2020. 1. 2. 12:29
728x90

 

 


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 로 변환 후 사용되었다. 

 

참조 : https://docs.python.org/3/glossary.html#term-iterable


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

참조 : https://docs.python.org/3/glossary.html#term-iterator

 

 

728x90