>>> a = map(int, ["1", "2", "3"])
>>> print(list(a))
>>> print(list(a))
위와 같은 코드를 실행시키면 어떤 값이 출력될까요?
정답은
>>> a = map(int, ["1", "2", "3"])
>>> print(list(a))
[1, 2, 3]
>>> print(list(a))
[]
입니다.
어째서 1, 2, 3이 담긴 배열이 두 번 출력되지 않는지 iterable과 iterator를 통해 알아봅시다.
1. Iterable
Iterable은 반복할 수 있는 객체입니다. Iterable은 for 문에서 사용할 수 있습니다. list, str, tuple, dict, set 등은 모두 Iterable 객체입니다. 이러한 Iterable 객체는 __iter__()라는 매직 메서드를 가지고 있습니다.
Iterable은 내장 함수 dir()을 사용하여 확인하면 __iter__() 매서드를 가지고 있습니다.
>>> a = [1, 2, 3]
>>> dir(a)
[(생략), '__iter__', (생략)]
Iterable 객체는 __iter__() 메서드를 사용하거나 iter()라는 내장 함수에 인자로 넘겨 Iterator 객체를 생성할 수 있습니다.
>>> a_iter1 = iter(a)
>>> a_iter2 = a.__iter__()
>>> type(a_iter1)
<class 'list_iterator'>
>>> type(a_iter2)
<class 'list_iterator'>
Iterable이 아닌 객체를 for 문에서 사용하면 Type Error가 발생합니다.
>>> for i in 123:
... print(i)
TypeError: 'int' object is not iterable
https://docs.python.org/3/glossary.html#term-iterable
Glossary
>>>, The default Python prompt of the interactive shell. Often seen for code examples which can be executed interactively in the interpreter.,,..., Can refer to:- The default Python prompt of the i...
docs.python.org
2. Iterator
Iterator는 차례대로 값을 하나씩 꺼낼 수 있는 객체입니다. Iterator는 Iterable 객체를 통해 생성할 수 있습니다. 이러한 Iterator 객체는 __next__()라는 매직 메서드를 가지고 있습니다.
Iterator 객체의 __next__() 메서드를 사용하거나, 내장 함수 next()의 인자로 Iterator를 넘겨 값을 하나씩 꺼낼 수 있습니다. 더 이상 꺼낼 값이 없을 때는 StopIteration 예외가 발생합니다.
>>> next(a_iter1)
1
>>> next(a_iter1)
2
>>> next(a_iter1)
3
>>> next(a_iter1)
StopIteration
>>> a_iter2.__next__()
1
>>> a_iter2.__next__()
2
>>> a_iter2.__next__()
3
>>> a_iter2.__next__()
StopIteration
Iterator 객체도 Iterable 객체입니다. Iterator를 iter()의 인자로 넘기거나 __iter__()를 사용하면 자기 자신이 나옵니다. 따라서 새로운 Iterator를 만들기 위해서는 Iterable을 통해서 만들어야 합니다.
>>> id(a_iter1)
4343740976
>>> id(iter(a_iter1))
4343740976
>>> id(a_iter1.__iter__())
4343740976
https://docs.python.org/3/glossary.html#term-iterator
Glossary
>>>, The default Python prompt of the interactive shell. Often seen for code examples which can be executed interactively in the interpreter.,,..., Can refer to:- The default Python prompt of the i...
docs.python.org
글의 맨 처음에 코드 기억나시나요?
>>> a = map(int, ["1", "2", "3"])
>>> print(list(a))
[1, 2, 3]
>>> print(list(a))
[]
이와 같이 list(a)
의 값이 달랐던 이유는 바로 map함수가 리턴하는 값이 Iterable이 아니라 Iterator였기 때문입니다.
zip() 함수 또한 Iterator를 리턴하는데요, 이런 함수들을 사용할 때는 Iterable과 Iterator를 잘 구분하여야겠습니다.