이터러블(iterable)
이터러블은 반복 가능한 객체를 의미합니다. 즉, 리스트(list), 튜플(tuple), 문자열(str), 딕셔너리(dictionary) 등과 같이 for문을 통해 하나씩 값을 가져올 수 있는 객체입니다. 이터러블은 iter 메서드를 구현하여 이터레이터(iterator)를 반환할 수 있습니다.
이터레이터(iterator)
이터레이터는 이터러블에서 값을 하나씩 가져오는 객체입니다. 즉, 이터러블에서 iter 메서드를 통해 반환된 이터레이터 객체는 next 메서드를 구현하여 이터러블의 다음 값을 반환할 수 있습니다. 이터레이터는 값이 모두 반환되었을 때 StopIteration 예외를 발생시켜야 합니다.
제너레이터(generator)
제너레이터는 이터레이터를 생성하는 함수입니다. 일반적인 함수와는 달리, yield 키워드를 사용하여 값을 하나씩 반환합니다. 제너레이터 함수를 호출하면 이터레이터 객체가 반환되며, next 메서드를 통해 값을 하나씩 가져올 수 있습니다. 제너레이터는 이터러블이며, iter 메서드와 next 메서드를 모두 구현합니다. 제너레이터는 함수 내부에 상태를 유지할 수 있으므로, 복잡한 연산을 수행할 때 유용합니다.
각각의 개념은 서로 연관되어 있지만, 목적과 사용 방법이 다르므로 예시를 통해 차이를 이해해보겠습니다.
my_list = [1, 2, 3]
for item in my_list:
print(item)
위 예시에서 my_list는 이터러블입니다. for문을 통해 리스트의 각 원소를 순회(iteration)하면서 출력할 수 있습니다. 이터러블은 내부적으로 iter 메서드를 구현하여 이터레이터를 생성할 수 있습니다.
my_list = [1, 2, 3]
my_iterator = iter(my_list)
print(next(my_iterator)) # 1
print(next(my_iterator)) # 2
print(next(my_iterator)) # 3
위 예시에서 iter 함수를 통해 리스트의 이터레이터를 생성하고, next 함수를 통해 이터레이터에서 값을 하나씩 가져올 수 있습니다. 이터레이터는 next 메서드를 구현하여 이터러블의 값을 하나씩 반환합니다.
def my_generator():
yield 1
yield 2
yield 3
for item in my_generator():
print(item)
위 예시에서 my_generator 함수는 제너레이터입니다. yield 키워드를 사용하여 각 숫자를 반환하고, 함수를 호출하여 제너레이터 객체를 생성합니다. for문을 통해 제너레이터의 각 값을 순회하면서 출력할 수 있습니다. 제너레이터는 이터러블이면서, iter 메서드와 next 메서드를 모두 구현합니다. 제너레이터는 함수 내부에 상태를 유지할 수 있으므로, 복잡한 연산을 수행할 때 유용합니다.
이러한 예시를 통해 이터러블, 이터레이터, 제너레이터의 차이를 이해할 수 있습니다. 이터러블은 반복 가능한 객체이며, 이터레이터를 생성할 수 있는 객체입니다. 이터레이터는 이터러블에서 값을 하나씩 가져오는 객체이며, next 메서드를 구현합니다. 제너레이터는 이터러블이면서, 이터레이터를 생성하는 함수이며, yield 키워드를 사용하여 값을 하나씩 반환합니다.
이터레이터는 값을 차례대로 꺼내 쓸 수 있는 객체라고 얘기 할 수 있다. 이터레이터를 사용함으로써 데이터 처리시에 모든 데이터를 메모리에 로드 시키지 않고 , 필요한 데이터를 요청 받을때 마다 메모리에 생성하여 전달 한다. 그럼으로서 , 메모리 사용의 효율성과 처리 속도를 향상 시킬 수 있다. 메모리 사용량이 높아지면 처리 속도 역시 느려지게 된다.
이터레이터를 생성하는 방법에는 이터러블 객체를 사용하는 방법과 제너레이터를 사용하는 두가지 방법이 있다.
이터러블 객체로 생성한 데이터가 메모리에 로딩이 되어 있어서 , 여러번 반복 사용이 가능 하다.
제네레이터로 생성한 데이터는 메모리에 로딩 하지 않으며 , 요청할 때마다 그때 그때 생성 해서 반환한다.
그래서 제너레이터를 len()으로 데이터 길이를 확인 하면 에러가 난다. 그리고 이터러블 객체 와 제너레이터를 각각 2개씩 생성 하여 id() 메모리 주소를 확인 해보면 이터러블한 객체는 다른 메모리 주소가 제너레이터로 생성한 객체는 같은 메모리 주소가 표시 됨을 알 수 있다.
그렇기 때문에 이터러블한 객체는 반복적으로 사용이 필요한 경우에 ,
제너레이터는 수치연산이나 temp , 스크래치 처럼 반복 사용이 필요 없는 목적으로 사용을 하게 되면 메모리 용량을 효율적으로 사용이 가능 하다고 생각한다.