이제는 좀 구분하자! 파이썬 Iterable,
iterator, iterable 왜 알아야 할까?
1. 효율적인 메모리 사용
이터러블과 이터레이터를 활용하면 큰 데이터를 메모리에 모두 올리지 않고도 처리할 수 있습니다. 이터레이터는 필요한 순간에만 데이터를 하나씩 가져오기 때문에, 대용량 데이터 처리 시 메모리 사용을 최소화할 수 있습니다.
예를 들어, 100만 개의 요소를 가진 리스트를 모두 메모리에 올리는 대신, 이터레이터를 사용하여 한 번에 하나씩 요소를 처리하면 메모리 효율이 크게 향상됩니다.
2. 지연 평가(Lazy Evaluation)
이터레이터는 필요할 때만 데이터를 생성하는 지연 평가를 지원합니다. 이는 성능을 최적화하고 불필요한 계산을 피할 수 있게 합니다.
예를 들어,
range()
함수는 실제 리스트를 생성하지 않고 이터레이터를 반환하여, 필요할 때만 숫자를 생성합니다. 이는 메모리와 시간 자원을 아끼는 데 유리합니다.
3. 커스터마이징과 확장성
이터레이터와 이터러블을 이해하면, 직접 커스텀 이터레이터를 만들어 특정한 반복 동작을 정의할 수 있습니다. 예를 들어, 파일의 각 줄을 읽어들이거나, 무한히 값을 생성하는 이터레이터를 만들 수 있습니다.
이를 통해 코드의 유연성과 재사용성을 높일 수 있습니다.
4. 파이썬의 기본 동작 원리 이해
- 파이썬의 많은 내장 함수와 문법(예:
for
루프,map()
,filter()
,zip()
)은 이터러블과 이터레이터를 기반으로 동작합니다. 이를 이해하면, 파이썬의 이러한 기본 기능들을 더 잘 활용할 수 있고, 어떤 상황에서 어떻게 동작하는지를 명확히 알 수 있습니
Iterable == 반복 가능한 객체
iterable
== 한 번에 하나의 원소를 반환하는 객체! 만약에 반복문으로 해당 객체를 순회 할 수 있다면 그 객체는 iterable 하다고 할 수 있다(=iterable 객체이다)파이썬 공식문서에서 의하면 이터러블은 한 번에 하나의 원소를 반환하는 객체로 우리가 자주 사용하는 데이터 타입(
list
,dict
,str
)은 보통iterable
이라고 생각하면된다.for loop
이나zip
,map
에서 사용될 수 있다면iterable
이다.
>>> for i in "abcd": # "abcd" 너도 iterable
... print(i)
...
a
b
c
d
iterable
은 내장함수iter()
의 입력으로 들어가고 출력으로 iterator가 나온다!‼‼‼iter(iterable)
->iterator
사용자가 만든 클래스에
__iter__
나__getitem__
이 정의되어있다면 모두iterable
이다
Iterator == 반복 가능한 객체(iterable
)를 하나씩 순차적으로 처리하기 위해 사용되는 객체
iterator
== 리스트, 튜플, 딕셔너리, 집합과 같은 반복 가능한 객체(iterable
)를 하나씩 순차적으로 처리하기 위해 사용되는 객체내장함수 iter(
iterable
)의 반환값이고, 내장 함수next(iterator)
의 입력으로 들어갈 수 있다. iterable이 iterator 엄마다iterator.__next__()
를 반복적으로 호출하면 원소들이 순차적으로 반환된다!
cute_zoo = ['bear', 'lion', 'tiger'] # iterable
zoo_iterator = iter(cute_zoo) # iterator
print(zoo_iterator) # <list_iterator object at 0x105038d30>
print(next(zoo_iterator)) # cute_zoo 첫번째 원소 반환 - bear
print(next(zoo_iterator)) # cute_zoo 두번째 원소 반환 - lion
print(next(zoo_iterator)) # cute_zoo 세번째 원소 반환 - tiger
print(next(zoo_iterator))
>>> Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
이터레이터에서 next를 통해 모든 원소를 다 순회하고 next() 호출 시
StopIteration
예외가 발생한다. 이 예외는 정상적인 동작으로, 이터레이터가 끝났다는 신호를 주는 역할을 한다그러나 이터러블 객체 자체는 직접적으로 요소를 하나씩 반환하지 않지만 이터레이터는 next()를 통해 이터러블 객체의 요소를 하나씩 순차적으로 반환 할 수 있다!
어? 근데 for loop에서 iterable사용해서 원소 하나씩 뽑을 수 있잖아?
iterator와 iterable의 가장 큰 차이점은 위에서 말씀드릴 것 처럼 직접 원소를 반환하는지의 여부였습니다.
근데 이상하죠? for loop의 인자로 iterable이 들어가 원소를 하나씩 반환할 수 있는데!? -> 사실 for loop 내부적으로 iter를 호출해 원소들을 뽑아 준답니다. 파이썬 사용자들이 직접 iterator내 원소에 접근할려고 iter(이터러블)을 호출할필요가 없는거죠
my_list = [0,1,2] for i in my_list: print(i)
for
루프가 시작되면, 내부적으로 파이썬은 먼저 이터러블 객체에 대해iter()
를 호출하여 이터레이터를 생성합니다.이터레이터는 이 리스트의 첫 번째 요소를 가리키는 상태로 초기화됩니다.
그 다음, 루프가 반복될 때마다 이터레이터의
next()
메서드를 호출하여 다음 요소를 가져옵니다.모든 요소가 반환된 후에는
StopIteration
예외가 발생하지만,for
루프는 이 예외를 자동으로 처리하여 루프를 종료합니다.
iterable와 iterator의 차이
이터러블 객체 자체는 직접적으로 요소를 하나씩 반환하지 않지만 이터레이터는 next()를 통해 이터러블 객체의 요소를 하나씩 순차적으로 반환 할 수 있다!
iterable
이iterator
를 포함한다 (이터러블이 더 큰 개념)모든
iterable
로iterator
를 만들 수 있다! (iter(이터러블객체)
반환 값이iterator
)>>> print(iter([1,2,3,4,5])) <list_iterator object at 0x106aa4a00>
- 하지만 모든
iterator
는iterable
이지만 그 역은 성립하지 않는다. (모든 이터러블이 이터레이터인것은아님)
>>> print(next([1,2,3,4,5]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not an iterator
[1,2,3,4,5]
는 iterable이다 하지만 iterator
가 아니기에 next의 인자가 될 수 없다!
사용자 정의함수에서
iter()
를 구현했다면 ->iterable
사용자 정의함수에서
iter()
와next()
를 둘 다 구현했다면 ->iterator