이번에 정리할 내용은 python에서 일반적으로 자주 사용되지는 않지만 알아두면 유용할 수도 있는 generator이다. generator는 lazy iterator를 return하는 함수로 이야기된다. 들여다보면 for 문과 상당히 유사하지만 메모리 처리에 있어서 다른 모습을 나타낸다.
Generator의 뜻, 예시
Generator는 iterator를 생성해주는 함수이다. 생성된 Generator 객체를 통해서 for문을 이용하여 사용할 수 있다.
예를 들어서, 어떤 숫자를 입력 받아서 1부터 입력받은 숫자 중 7의 배수만을 리턴하는 함수가 있다고 해보자.
def multiple_of_seven(num):
return_lst = []
for i in range(1, num+1):
if i % 7 == 0: return_lst.append(i)
return return_lst
print(multiple_of_seven(100))
[7, 14, 21, 28, 35, 42, 49, 56, 63, 70, 77, 84, 91, 98]
100을 입력한 경우엔 위처럼 list가 리턴될 것이다.
그런데 만약 이 list의 원소들을 하나씩 출력해야할 때, 혹은 이 list를 돌면서 무언가 작업을 수행할 때 우리는 일반적으로 for문을 사용한다. 그래서 다음과 같이 코드를 작성한다.
for element in multiple_of_seven(100):
print(element)
그리고 다음과 같이 출력되는 결과를 얻을 수 있다.
7
14
21
28
35
42
49
56
63
70
77
84
91
98
이제 Generator를 사용해보자.
Generator는 함수 안에서 yield 키워드를 사용해서 만들 수 있다.
def multiple_of_seven_by_Gen(num):
for i in range(1, num+1):
if i % 7 == 0: yield i
print(multiple_of_seven_by_Gen(100))
코드를 살펴보면, 1부터 num+1까지의 숫자 중, 7의 배수인 경우 yield 하도록 되어있다.
출력했을 때의 결과는 아래와 같다.
<generator object multiple_of_seven_by_Gen at 0x0000021C88EC5460>
어떤 list가 return이 된 게 아니고, generator를 생성하였다.
출력을 할 때에는 for 문을 사용하면 된다.
for i in multiple_of_seven_by_Gen(100):
print(i)
7
14
21
28
35
42
49
56
63
70
77
84
91
98
그러면 list와 비슷한 형태인 Generator를 사용하는 이유는 뭘까?
가장 큰 특징은 Generator 객체는 element들을 메모리에 저장하지 않는다.
만약에 매우 긴 list를 하나 가지고 있어서 그걸 iteration 하면서 작업을 해야한다고 한다면, python은 그 element들을 모두 메모리에 저장해야 한다. 하지만 Generator는 그 모든 element들을 저장하지 않고 필요할 때 사용할 수 있게 해준다. range와 똑같은 형태라고 생각하면 된다.
next와 iter 함수
다음으로는 Generator와 연관된 next와 iter 함수에 대해서 알아보자.
next function
우선 next 함수는 Generator 객체에서 다음 element를 하나씩 꺼내 쓸 때 사용한다. 다음 element로 넘어가게 하는 기능인데, 솔직히 언제 쓸 수 있을지는 잘 모르겠지만 .. 일단 써 본다.
generator_example = multiple_of_seven_by_Gen(50)
print(next(generator_example))
print(next(generator_example))
print(next(generator_example))
print(next(generator_example))
print(next(generator_example))
print(next(generator_example))
print(next(generator_example))
숫자의 범위를 줄여서 50까지의 숫자 중 7의 배수만을 담은 Generator를 generator_example로 만들었고, next 함수를 사용해서 하나씩 출력해보았다.
7
14
21
28
35
42
49
짠. 어려운 건 없다.
iter function
iter는 iterator가 아닌 object를 iterator로 만들어주는 함수이다.
gen_str = "Generator"
for i in gen_str:
print(i)
print("===============")
gen_str_iter = iter(gen_str)
print(gen_str_iter)
for i in gen_str_iter:
print(i)
G
e
n
e
r
a
t
o
r
===============
<str_ascii_iterator object at 0x0000021C889A5030>
G
e
n
e
r
a
t
o
r
이제 위의 코드를 살펴보자.
처음에는 string을 담은 object를 for 문을 돌면서 출력했다.
두 번째는 그 object를 iter함수에 인자로 넣어서 iterator 객체로 변환하였다.
그래서 객체를 출력했을 때에는 string이 나오지 않고 class에 대한 내용이 나타났다.
하지만 for 문을 통해서 각 문자들을 추출하는 데에는 동일한 코드가 사용되었다.
일반적인 작업을 하는 데에 list 안에 있는 원소들에 대한 메모리 걱정을 하는 일은 별로 없겠지만, 그래도 기본이 되는 내용이니 꼭 알아두자. 끝.
'Pyhon 기초, 실전' 카테고리의 다른 글
[Python 기초] collections module 소개: counter, namedtuple, defaultdict (0) | 2023.07.23 |
---|---|
[Python 기초] lambda, filter function: 아는 사람만 쓰는 함수 (0) | 2023.07.22 |
[Python 기초] map: 아는 사람만 쓰는 built-in function (0) | 2023.07.19 |
[Python 기초] 날짜 및 시간 다루기: datetime module 소개 (0) | 2023.07.18 |
[Python 기초] list, dictionary comprehension and conditional comprehension (1) | 2023.07.17 |