티스토리 뷰
본 포스팅은 코딩을 처음 배우시는 입문자 분들께는 적절하지 않은 포스팅일 수 있습니다.
개발에 필요한 최소한의 내용만 정리해서 포스팅합니다.
Summary 📜
- Generator와 yield에 대한 이해
yield를 알기에 앞서... 🤔
파이썬에는 yield라는 키워드가 있다. yield를 찾다 보면, generator라는 개념도 나오고, 이해가 잘 안 될 수 있다. 그래서 yield 키워드를 이해하기 위해 Generator라는 개념을 먼저 알고 이해하자.
Generator란? 🤔
제네레이터(Generator)란 메모리를 효율적으로 사용하면서 반복을 수행하도록 돕는 객체(iterator 라고도 한다.)이다. 이게 무슨 말인가? 우리가 지금까지 수행했던 반복문은 효율적이지 않다는 것일까? 아래의 예제를 보자.
def list_number(number):
result = []
for i in range(1,number+1):
result.append(i)
return result
print(list_number(10))#길이가 10인 리스트가 출력됨 [1,2,...,10]
위와 같이 반복이 존재하는 구간은 반복문을 활용해서, 사용해왔다. 그러나, 만약에 number가 몇십억이라면 어떨까? 몇십억의 반복문을 수행하고, 심지어 반환 값을 위해 받아야 하는 리스트도 몇십억짜리 리스트를 반환해야 한다. Generator는 이러한 부분을 조금 더 효율적으로 접근하고자 고안되었다. 그렇다면 'Generator를 쓰는 것이 왜 효율적인 것인가?'에 대해 궁금할 수 있다. 왜 효율적이라고 하는지 알아보자.
Iterable(반복 가능한) 특징 🔗
Generator 객체는 내부적으로 __iter__() 함수를 가지고 있다. __iter__()함수는 set, list, tuple 등 다양한 객체에서 가지고 있는데, __iter__() 함수가 있다는 것은 반복문을 통해 요소를 추출할 수 있음을 의미한다. 이를 반복 가능한 객체(iterable)하다고 말하는데, generator 객체 또한 반복 가능한 객체이다. 추가적으로 __next__() 함수가 존재하는데, 이를 통해 아래 그림과 같은 형식으로 요소를 하나씩 불러올 수 있다. 직접 호출할 수도 있지만, __iter__() 함수를 통해 내부적으로 __next__() 함수를 호출하며, 마지막 요소에 도달할 때까지 진행한다.
즉, 미리 요소를 리스트에 만들어 놓고, 꺼내는 것이 아니라, __next__() 함수를 통해서 필요할 때마다 접근하여 요소를 빼낸다. 여기서 의문점이 존재할 수 있다. '특정 위치를 어떻게 기억하지 ?' 필요할 때마다, 내부적으로 필요한 요소에 접근하기 위해서는 현재 상태를 기억해야 한다. 그것을 표현하기 위한 키워드가 'yield'다.
yield 란? 🤔
yield를 표현하기 위해 정말 오래 돌아왔다. yield라는 영단어는 '양보하다'의 뜻이 있다. yield 키워드는 해당 키워드 라인을 실행하고 함수를 호출한 쪽으로 프로그램의 제어를 넘겨준다. 예제를 통해 알아보자.
def yield_test():
for i in range(5):
yield i
print(i,'번째 호출!')
print(type(yield_test())) # <class 'generator'>
#CaseA. __next__() 함수를 통해 출력
t = yield_test()
print(t.__next__()) # 0
print(t.__next__()) # 0 번째 호출! 1
print(t.__next__()) # 1 번째 호출! 2
print(t.__next__()) # 2 번째 호출! 3
print(t.__next__()) # 3 번째 호출! 4
#print(t.__next__()) #Error
#for문을 이용하여 출력
print("<-->")
for k in yield_test():
print(k)
#CaseB. result
# 0
# 0 번째 호출!
# 1
# 1 번째 호출!
# 2
# 2 번째 호출!
# 3
# 3 번째 호출!
# 4
# 4 번째 호출!
CaseA를 보자. __next__() 함수가 실행되면, yield 키워드의 i인 0을 넘겨주고 멈춘다. 다시 __next__()가 실행되면, yield의 바로 밑 키워드인 print(i,'번째 호출')이 출력되고, 다시 반복문을 돌아서 yield 키워드를 만나 i를 반환하게 된다.(CaseB번과 비교해보았을 때, 직접 next 함수를 통해 실행하면 마지막 print부분이 출력이 안 되는 부분도 발견한 것 같다. 내부적으로 약간 차이가 있는 것으로 생각됨.) 핵심은 yield 키워드에서 함수가 끝나지 않은 상태로 대기하고 있는 것이다. 이렇게 yield 키워드를 통해 generator 객체를 만든다면, 필요할 때 마다 해당 객체를 통해 요소를 반환할 수 있다. 함수를 완전 실행시키는 것이 아니라, 일부를 실행시키고 일시 정지하기 때문에, 함수의 재사용성이 높아진다. 또한 전체를 메모리에 저장할 필요가 없다는 점에서 굉장히 효율적이다.
사용법 🔎
yield 키워드는 함수에서 사용한다. yield 키워드 자체가 generator 객체를 만들기 위한 함수 내에서 필요한 실행 키워드 이므로 함수 내에서 사용한다. 함수 내에서 요소에 해당하는 부분을 yield 키워드 라인에 넣으면 된다.
위 코드에서는 0부터 5까지 숫자를 반환하는 함수를 만들었기 때문에, i가 yield 키워드 라인에 들어갔다.
정리 📦
- yield 키워드는 호출한쪽으로 프로그램 제어를 넘겨주는 키워드이다.
- 함수 내에서 사용한며,generator객체를 생성한다.
- generator 객체는 iterator(반복성) 객체이다.
- 해당 키워드는 필요할 때 마다 요소를 출력하므로, 메모리 관점에서 효율적이다.
결론 🔑
제어를 양보한다 라는 표현만 가지고는 완전히 이해하기 어려웠는데, 포스팅을 쓰면서, yield 키워드의 작동방식을 정확하게 이해하게 된 것 같다. 최근 selenium을 배우고 있는데, yield 키워드를 이용해 요긴하게 요소를 가져오고 있다. 익숙해지니, 오히려 더 쓰기 편한 것 같기도 하다. 익숙하지 않은 개념이라, 약간 난해 할 수 있지만, 써보면 generator와 iterator, iterable의 개념에 대해서도 쉽게 이해할 수 있게 될 것이다.
References 📑
- https://tech.ssut.me/what-does-the-yield-keyword-do-in-python/
- https://yeomko.tistory.com/113
- https://dojang.io/mod/page/view.php?id=2412
'공부 > Python' 카테고리의 다른 글
[Python] 빠르게 배우는 파이썬 - 2. 함수와 파리미터(+람다 함수) (0) | 2022.01.03 |
---|---|
[Python] 빠르게 배우는 파이썬 - 1.파이썬과 자료형 (0) | 2021.12.27 |
- Total
- Today
- Yesterday
- 재귀
- 백준
- 프로그래머스
- JNDI연동
- Spring
- Python
- 프로그래머스 문제정복
- 아기상어나쁜상어
- 브루트포스
- 코딩테스트
- 실패일기
- java
- DP
- 유클리드-호제법
- looker instance 접속
- 카카오
- DFS
- looker core
- 자바
- 아기상어미워
- BFS
- 9019
- 파이썬
- 하루 회고
- Database
- dml
- 플루이드 와샬
- value annotation
- 그래프 탐색
- db
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |