데이터분석 기록일지

파이썬

[Python] 이터러블(iterable) vs 이터레이터(iterator)

야하루 2024. 7. 21. 13:00

이터러블(iterable)

이터러블은 순회(반복) 가능한 객체를 말한다.

즉, 가지고 있는 원소들을 한 번에 하나씩 돌려줄 수 있는 객체이다.

이터러블은 순회를 "당한다"고 이해하면 좋다. 

 

리스트, 튜플, 문자열, 딕셔너리, 집합, range 등이 이터러블에 해당한다.

가장 간단하게는 for 문에 들어갈 수 있는 객체라고 이해하면 좋다

 

또한 이터러블은 "__iter__() 라는 메서드를 이용하여 이터레이터를 생성할 수 있는 객체" 로 정의된다.

__iter__() 는 이터러블의 이터레이터를 생성할 수 있는 함수이다. 

 

 

이터레이터(iterator)

이터레이터는 이터러블의 순회를 주관하는 객체이다.

(이터러블은 순회를 '당하는' 것이고, 이터레이터가 순회를 '행하는' 개념이다.)

 

이터레이터는 이터러블에서 값을 하나씩 가져오는 객체이다.

이터레이터는 이터러블 객체로부터 값을 순차적으로 가져올 수 있게 해주며,

이 과정에서 이터레이터의 메소드 __iter__()__next__()를 사용하는데,

이 두 메소드를 가지는 것을 이터레이터 라고 정의한다.

 

 

앞서 __iter__()는 이터레이터를 생성하는 함수라고 하였다.

이터러블에서 __iter__() 메서드를 호출하면 이터레이터인 자기 자신이 반환된다.

또한 이터레이터는 이터러블을 순회하기 때문에, 한 원소에 접근했으면 그 다음 원소로 넘어가야 하는데, 이를 수행해주는 것이 __next__() 메서드이다.

__next__() 를 사용하여 현재 접근한 원소를 반환하고, 다음 원소로 이동할 수 있다.

모든 원소를 순회하고 나면 'StopIteration'이라는 에러가 발생하며 순회가 종료되게 된다.

 

 

((-> 이터레이터는 다른 문자열이나 리스트같이 특정 값을 가지는 객체가 아니라, '순회'라는 역할을 수행하는 객체이다.

'순회' 라는 역할을 하는 새로운 개념의 객체라고 생각하는게 편하다.

이터레이터는 순회하면서 이터러블의 요소를 보여줄 뿐인거지, 그 요소의 값을 직접 가지는 건 아니라는 것))

 -> 참조하면서 상태 유지임. 수정하기.

 

 

__iter__() 메서드:

__iter__() 메서드는 이터러블 객체에서 호출된다.

이 메서드는 이터레이터 객체를 생성하고 반환한다.

이터러블 객체의 __iter__() 메서드를 호출하면 해당 이터러블에 대한 이터레이터 객체가 생성되며,

이터레이터에서의 __iter__()은 자기 자신을 반환한다.

 

 

 

__next__() 메서드:

__next__() 메서드는 이터레이터 객체에서 호출된다.

(이터레이터는 __iter__()와 _next__() 메소드를 가지고 있어야만 한다.)

 

이 메서드는 다음 값을 반환하고, 이터레이터의 내부 상태를 업데이트한다.(현재 원소를 반환했으면 다음 원소로 넘어감)

이터레이터 객체는 __next__() 메서드를 사용하여 현재 접근한 원소를 반환하고 다음 원소로 이동한다.

모든 원소를 순회하고 나면 StopIteration 예외가 발생하며 순회가 종료된다.

이터러블을 1바퀴 다 돌았으면 더이상 해당 이터레이터로 __next__()를 이용하며 순회할 수 없다.

더 돌고 싶으면 새로운 이터레이터를 생성해야 한다.

 

 

=> 여기서 알 수 있듯이, __iter__()메소드를 가지는 것은 이터러블이다. 그런데 이터레이터도 __iter__()를 가진다.

따라서 이터레이터는 항상 이터러블이라고 정의할 수 있다.

 

 

여기서 들었던 의문점

-> 이터레이터 자기 자신을 나타낼뿐인 __iter__()는 이터레이터에 왜 필요한가?

 

= 이터레이터는 이터러블 객체를 반복하여 순회해야 하기 때문에, 자기 자신도 이터러블처럼 동작할 수 있어야 한다.

그렇기에 이터레이터는 __iter__() 메서드를 가짐으로써 이터러블로 정의 내려질 수 있어야 한다.

(__iter__() 메서드를 구현하여 이터러블로도 정의된다.)

(앞서 말한, 이터러블 : 순회 가능한 객체)

 

 

  • "<list_iterator object at 0x7de5aee5c520>"는 이터레이터 객체의 표현입니다. 이 값은 메모리 주소를 나타내며, 새로운 이터레이터를 생성할 때마다 변경됩니다. 이는 파이썬 내부에서 이터레이터 객체를 구분하기 위한 고유한 식별자입니다.

<list_iterator object at 0x7de5aee5c520>"는 이터레이터 객체의 식별자를 나타내는 값입니다.

-> id()와 출력 형태가 다른 것은 10진수와 16진수 차이.

 

 

 

 

이터레이터는 그냥 그대로 출력하면 이터레이터 객체의 메모리 주소(식별자)를 반환하므로, 우리가 원하는 값을 볼 수 없다.

원하는 값을 반환하기 위해서는 앞서 말했듯이 __next__()메서드를 써주면 된다.

 

하지만 next함수가 아닌 for문, list(), tuple(), dict() 등의 함수에 넣어주어도 이터레이터의 값이 반환되는 것을 볼 수 있다.

그 이유는 이들 함수 내부에 모두 이터레이터 역할이 존재하기 때문이다.

(이터레이터는 이터러블이라 하고 여기서 이터러블은 또 이터레이터라고 하면서 둘은 다르다고 하니까 짜증이 난다.)

분명 시작하면서 저들은 이터러블이라고 하였다.

하지만 여기서 '이터레이터' 가 존재 한다는 것은 이 이터러블한 객체의 '함수'를 말한다.

 

예를 들어

my_list = [1,2,3,4]

-> 여기서 my_list는 리스트라는 객체이다. 이 my_list는 이터러블이지만 이터레이터는 아니다.

 

tuple1 = (1,2)

list(tuple1)

-> 여기서 사용된 list()는 함수이다. 이 list()함수가 내부적으로 이터레이터를 생성할 수 있다.

이 생성된 이터레이터를 사용하여 주어진 이터러블 객체의 요소들에 접근한다. 이터레이터가 있으니 __next___() 메서드도 내부에 존재하고 다음 값을 반환하여서 리스트로 변환한다.

 

list()함수나 tuple() 함수 등은 인자로 이터러블을 받는데, 이터레이터는 이터러블이기 때문에, 이터레이터 결과를 해당 함수에 넣어주어도 원하는 결과 값이 반환되는 것이다.

 

 

 

 

https://velog.io/@clueless_coder/%ED%8C%8C%EC%9D%B4%EC%8D%AC-iterable%EA%B3%BC-iterator-%EC%9D%98-%EC%B0%A8%EC%9D%B4%EA%B0%80-%EB%AD%90%EC%98%88%EC%9A%94

 

[파이썬] iterable과 iterator 의 차이가 뭐예요?

"뭐에요? 🤨" 시리즈 1편 평소에 헷갈렸던 것들이나 암기해두면 좋을 것들, 대강 알고 정확한 정의를 몰랐던 것들을 좀 깊게 들어가보면서 쭉 질문별, 문제상황별로 포스트를 작성해보겠다.

velog.io

 

'파이썬' 카테고리의 다른 글

[Pandas] 기본 함수 정리  (0) 2024.08.16
[Python] 참조(Reference) + 복사(Copy)  (0) 2024.07.05
map()함수  (0) 2024.06.09
lambda()함수  (0) 2024.06.09
리스트 컴프리헨션(list comprehension)  (0) 2024.06.09