Python/파이선과 친해지기

[Python] - Python과 매우 친해지기-Iterator와 Generator

예약어 시간 for문의 정의를 본 사람은 Iterable이라는 말을 보았을 것이다.(안 썼나?) 이번 시간에는 Iterator에 대해서 알아보면서 우리가 사용하는 반복문을 조금 더 높은 수준으로 올려보자


Iterable 한 것과 Iterator

Iterable 하다는 것은 문자 그대로 반복이 가능하다는 의미를 가진다. 즉 다음과 같은 객체들은 for, enumerate에서 반복할 수 있다.

Iterable 한 객체 : list, dict, set, tuple, range, str 등등

Iterable 한 객체들은 내부적으로 __iter__() 매소드를 가지고 있다. 이를 이용하여 아래와 같은 Iterator 객체를 생성할 수 있다.

>> my_list = [1,2,3,4,5,6,7,8,9,10]
>> my_iter = iter(my_list)

또한 Iterator로 생성된 객체는 next매소드를 가지고 있어, next를 이용하여 원소들을 탐색할 수 있다.

>>> my_list = [1,2,3,4,5,6,7,8,9,10]
>>> my_iter = iter(my_list)
>>> next(my_iter)
1
>>> next(my_iter)
2
>>> next(my_iter)
3
>>> next(my_iter)
4

## my_iter의 끝으로 가면 next호출 시 Exception이 발생한다.

 

Advanced For

향상된 for문은 다른 프로그래밍언어에서도 심심치 않게 볼 수 있는 것으로 Iterable 한 객체들의 원소를 반복자가 순회하는 것이다. 다음의 예시를 보자

## 코드 :
fruits = ["apple","orange","strawberry","kiwi"]

for i in fruits :
    print(i)

## 출력 :
apple
orange
strawberry
kiwi

한 가지 재미있는 점은 반복자가 인덱스였을 때(range()를 이용한 순회)는 원소의 수정이 가능했지만, A-for문을 통한 반복에서는 원소의 직접 수정이 안된다는 점이다.

## 코드 :
fruits = ["apple","orange","strawberry","kiwi"]

for i in fruits :
    i="ruin"

print(fruits)

for i in range(len(fruits)) :
    fruits[i] = "ruin"

print(fruits)

## 출력 :
['apple', 'orange', 'strawberry', 'kiwi']
['ruin', 'ruin', 'ruin', 'ruin']

 

Generator

이러한 Iterator는 지정된 자료구조말고도 Generator를 이용하여 사용자가 정의할 수 있다. 다음의 예시를 보자 

## 코드 : 
def my_iterator() :
    my_list = [1,2,3,4,5,6,7,8,9,10]
    for i in range(len(my_list)) :
        yield my_list[i]

a = my_iterator()
next(a)
next(a)
next(a)

## 출력 :
1
2
3

이렇게 생성된 generator는 A-for문에 사용할 수 있다.

## 코드 : 
def my_iterator() :
    my_list = [1,2,3,4,5,6,7,8,9,10]
    for i in range(len(my_list)) :
        yield my_list[i]

a = my_iterator()

for i in a :
    print(i)


## 출력 :
1
2
3
4
5
6
7
8
9
10

 

next를 호출하거나, 반복을할때 generator는 다음 yield를 호출하기 전까지 정지한 것과 같다. 다음의 예시를 보자

## 코드 : 
def my_iterator() :
    my_list = [1,2,3,4,5,6,7,8,9,10]
    for i in range(len(my_list)) :
        yield my_list[i]

a = my_iterator()

next(a)
next(a)

## 출력 :
currently were 0
currently were 1

 

Dictionary의 반복

이걸 배우기 까지 너무나도 많은 길을 걸어왔다. 우리들이 Advanced-For를 배울때까지 기다린 Dictionary에게 경의를 표하자 아래의 코드로 확인하자

## 코드 :
students = {"P_01":"CHEEL","O_02":"GLAADOS","R_03":"STEENLY"}

for index, value in students.items() :
    print(index, value)

## 출력 :
P_01 CHEEL
O_02 GLAADOS
R_03 STEENLY

students.items()는 우선 iterator는 아니다. 이는 dictionary의 특징을 생각하면 잘 알수 있는데, dictionary는 순서가 없다는것이다. 따라서 a = students.items()를 했을때 a는 dict_item이라는 객체로 출력됨을 알 수 있다.

 


이번 시간에는 iterable 한 객체와 나만의 Iterator를 생성하는 법, 늦게나마 Dictionary를 반복하는 방법과 Advanced for를 사용하는 방법을 배웠다. 이제 Python과 짱친먹을 시간도 얼마 남지 않았다. 다음 시간에는 내포(Comprehension)에 대해서 알아보도록 하자