이번 포스트는 파이썬 변수의 iterator과 iterable 타입에 대해 알아 보도록 한다.
iteration 관련 표준 함수
- iter() : 반복자를 리턴
- next() : 반복자가 가리키는 값을 반환하고, 반복자는 다음 요소로 이동
- reversed() : 뒤에서 부터 앞으로 순회하는 역 반복자 리턴
iterator
iterator는 우리말로 번역하면 반복자라고 하며, 객체가 가진 각 요소에 순차적으로 접근 할 수 있게 해주는 도구다. 파이썬에서는 iter() 표준 함수를 통해 얻을 수 있다.
아래 예제는 문자열 객체의 각 문자에 iterator를 이용하여 순차적으로 접근하는 것을 보여주고 있다.
s = 'ABCD'
itr = iter(s)
print(next(itr)) # A
print(next(itr)) # B
print(next(itr)) # C
print(next(itr)) # D
print(next(itr)) # error. Stopiteration exception
3 라인에서 iter(s) 표준 함수를 이용하여 문자열에 대한 iterator를 얻어 온 후 5~8 라인 동안 next(itr)을 이용하여 다음 요소에 접근하고 있다.
8 라인에서 이미 문자열의 끝까지 도착 했지만 9 라인에서 한번 더 next를 호출하고 있다. 이렇게 이미 끝까지 순회가 끝난 iterator의 다음 요소를 접근하려고하면 'StopInteration' 예외가 발생하게 된다.
만일 예외가 발생하는 것을 막고 싶다면 try ~ catch 문으로 감싸 예외 발생을 별도로 처리해주거나 next() 표준함수의 두번째 인자를 이용하는 방법이 있다. next() 표준 함수의 두번째 인자는 iterator에 더 이상 다음 요소가 없는 경우 예외를 발생시키는 대신 두번째 인자로 넘어온 값을 리턴한다.
...
print(next(itr)) # D
print(next(itr, -1)) # -1. 예외 대신 -1을 리턴한다.
next의 두번째 인자로는 어떤 값이든 올수 있으니 필요에 따라 -1이 아닌 None등을 리턴하여 iteration이 종료 조건으로 사용할 수도 있다.
반복자를 리턴하는 iter() 표준 함수 외에도 뒤에서 부터 앞으로 순회를 하는 역방향 반복자를 리턴하는 reversed() 표준 함수도 있다.
s = 'ABCD'
itr = reversed(s)
print(next(itr)) # D
print(next(itr)) # C
print(next(itr)) # B
print(next(itr)) # A
print(next(itr, -1)) # -1
iterable 타입
s = 'ABCD'
n = 10
f = 3.4
위 예제에서 s는 여러개의 문자로 이루어진 문자열 타입이며 위에서 반복자를 사용할 수 있다는 것을 보았다. 하지만 n과 f는 값 하나로만 이루어져 있으므로 반복자를 사용한다 것이 어울리지 않는다. 실제 위 코드를 실행 해보면 n과 f에서 'object in not iterable'이라는 예외를 발생 시킨다.
위의 문자열 s 처럼 iter() 함수로 반복자를 리턴할 수 있는 타입을 iterable 타입이라고 하며, 파이썬에서는 str, list, tuple, dictionary, set, range 와 같은 타입들이 iterable 타입이다.
특히 range는 타입은 반복자를 통해서 주어진 구간의 값을 순차적으로 얻을 수 있는 타입으로써 for 문 등에서 순차적으로 숫자를 증가하거나 감소 시킬 때 자주 사용된다.
- range(first, last, step) : first(포함)에서 시작해서 last이전(미포함) 까지 step 만큼 증가하거나 감소한다.
eg) range(1, 10) : 1, 2, 3, 4, 5, 6, 7, 8, 9
range(1, 10, 2) : 1, 3, 5, 7, 9
range(9, 1, -3) : 9, 6, 3 - range(count) : 0 베이스에서 count개 만큼의 값을 리턴한다.
eg) range(10) : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
for 를 이용한 iteration
파이썬의 for문은 C/C++, C#, Java 처럼 인덱스 기반이 아니라 iterable 타입을 순회한다.
for itr in interable_type :
expression
for문은 iterable 타입이라면 무엇이든 사용 할 수 있고, 다른 프로그래밍 언어 처럼 인덱스 기반 순회를 위해서는 range를 사용한다.
s = 'ABCD'
# 문자열은 iterable 타입이므로 순회 가능하다.
for itr in s : # A B C D,
print(itr)
# 위 예제와 동일하다
for itr in iter(s) : # A B C D
print(itr)
# 역순 순회
for itr in reversed(s) : # D C B A
print(itr)
# range 객체 또한 iterable 타입이므로 순회 가능하다.
for i in range(10) : # 0 ~ 1
print(i)
for i in range(10, 0, -1) : # 10 ~ 1
print(i)
마치며
이상 파이썬의 iteration과 iterable 객체에 대해 알아 보았다. iteration은 시퀀스 객체들의 순회와 제너레이터에서 자주 쓰이므로 제대로 숙지 하도록 하자.
다음 포스트에서는 인덱스와 요소를 동시에 리턴하는 이뉴머레이트(enumerate)에 대해 계속 알아 보도록 하겠다.