목차
파이썬에서 yield란 무엇인가?
파이썬의 yield 키워드는 유일한 반환값처럼 작동합니다.
차이점은 값을 반환하는 대신 호출자에게 생성기 개체를 반환한다는 것입니다.
함수가 호출되고 실행 스레드가 함수에서 yield 키워드를 찾으면 함수 실행은 해당 줄 자체에서 중지되고 생성자 객체를 호출자에게 다시 반환합니다.
Syntax
yield expression
설명
파이썬의 yield는 생성기 객체를 반환합니다. 제너레이터는 값을 얻기 위해 반복되어야 하는 특수 함수입니다.
yield 키워드는 주어진 표현식을 생성기 객체를 되돌려주는 생성기 함수로 변환합니다. 객체의 값을 얻으려면 yield에 주어진 값을 읽기 위해 반복되어야 합니다.
예 : Yield 메서드
다음은 yield의 간단한 예입니다. testyield() 함수에는 "Entity01 Python 자습서에 오신 것을 환영합니다"라는 문자열이 있는 yield 키워드가 있습니다. 함수가 호출되면 출력이 인쇄되고 실제 값 대신 제너레이터 객체를 제공합니다.
def testyield():
yield "Entity01 Python 자습서에 오신 것을 환영합니다"
output = testyield()
print(output)
출력 :
<generator object testyield at 0x000001F6B2F3C9C8>
주어진 출력은 우리가 yield 하기 위해 준 값을 가진 제너레이터(generator) 객체입니다.
그러나 우리는 결과에서 yield를하기 위해 제공해야 하는 메시지를 받지 못하고 있습니다!
yield 에 주어진 메시지를 인쇄하려면 아래 예제와 같이 제너레이터 객체를 반복해야 합니다.
def testyield():
yield "Entity01 Python 자습서에 오신 것을 환영합니다"
output = testyield()
for i in output:
print(i)
출력
Entity01 Python 자습서에 오신 것을 환영합니다
파이썬에서 제너레이터(Generator)는 무엇입니까?
제너레이터는 반복 가능한 제너레이터 객체를 반환하는 함수입니다. 제너레이터 객체의 값은 전체 리스트 대신 한 번에 하나씩 가져오므로 실제 값을 얻으려면 next() 또는 list() 메서드를 사용하여 for 루프를 사용할 수 있습니다.
제너레이터 함수의 사용
제너레이터 함수와 제너레이터 표현식을 사용하여 제너레이터를 생성할 수 있습니다.
제너레이터 함수는 반환 값을 갖는 대신 yield 키워드가 있는 일반 함수와 같습니다.
제너레이터 함수를 생성하려면 yield 키워드를 추가해야 합니다. 다음 예제에서는 제너레이터 함수를 만드는 방법을 보여줍니다.
def generator():
yield "H"
yield "E"
yield "L"
yield "L"
yield "O"
test = generator()
for i in test:
print(i)
출력
H
E
L
L
O
일반 함수와 제너레이터 함수의 차이점.
제너레이터 함수가 일반 함수와 어떻게 다른지 이해합시다.
normal_test() 및 generator_test() 2개의 함수가 있습니다.
두 함수 모두 "Hello World" 문자열을 반환한다고 가정합니다. normal_test()는 return을 사용하고 generator_test()는 yield를 사용합니다.
# Normal function
def normal_test():
return "Hello World"
#Generator function
def generator_test():
yield "Hello World"
print(normal_test()) #call to normal function
print(generator_test()) # call to generator function
출력
Hello World
<generator object generator_test at 0x000001F6B2E97748>
출력은 일반 함수 normal_test()를 호출할 때 Hello World 문자열을 반환함을 보여줍니다. yield 키워드가 있는 제너레이터 함수의 경우 문자열이 아닌 <generator object generator_test at 0x000001F6B2E97748>을 반환합니다.
이것이 제너레이터 함수와 일반 함수의 주요 차이점입니다. 이제 제너레이터 객체에서 값을 얻으려면 for 루프 내부의 객체를 사용하거나 next() 메서드를 사용하거나 list()를 사용해야 합니다.
print(next(generator_test())) # will output Hello World
일반 함수 v/s 제너레이터 함수에 추가할 또 하나의 차이점은 일반 함수를 호출할 때 실행이 시작되고 중지되고 반환 될 때 값이 호출자에게 반환된다는 것입니다. 따라서 실행이 시작되면 그 사이에 일반 기능을 중지할 수 없으며 return 키워드를 만날 때만 중지됩니다.
그러나 제너레이터 함수의 경우 실행이 시작되면 첫 번째 yield 를 만날 때 실행을 중지하고 제너레이터 객체를 반환합니다. 생성기 개체를 사용하여 값을 가져오고 요구 사항에 따라 일시 중지했다가 다시 시작할 수 있습니다.
제너레이터에서 값을 읽는 방법은 무엇입니까?
list(), for-loop 및 next() 메서드를 사용하여 제너레이터 객체에서 값을 읽을 수 있습니다.
사용 : list()
리스트는 대괄호 안에 요소가 있는 반복 가능한 개체입니다. 제너레이터 개체에서 list()를 사용하면 제너레이터가 보유하는 모든 값을 얻을 수 있습니다.
def even_numbers(n):
for x in range(n):
if (x%2==0):
yield x
num = even_numbers(10)
print(list(num))
출력
[0, 2, 4, 6, 8]
사용 : for-in
예제에는 정의된 n에 대해 모든 짝수를 제공하는 even_numbers() 함수가 정의되어 있습니다. even_numbers() 함수에 대한 호출은 for 루프 내부에서 사용되는 생성기 객체를 반환합니다.
def even_numbers(n):
for x in range(n):
if (x%2==0):
yield x
num = even_numbers(10)
for i in num:
print(i)
출력
0
2
4
6
8
사용 : next()
next() 메서드는 목록, 배열 또는 개체의 다음 항목을 제공합니다. 리스트가 비어 있고 next()가 호출되면 stopIteration 신호와 함께 오류가 반환됩니다. next()의 이 오류는 리스트에 더 이상 항목이 없음을 나타냅니다.
def even_numbers(n):
for x in range(n):
if (x%2==0):
yield x
num = even_numbers(10)
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num))
출력
0
2
4
6
8
Traceback (most recent call last):
File "<input>", line 11, in <module>
StopIteration
제너레이터는 일회용 입니다.
제너레이터는 경우 한 번만 사용할 수 있습니다. 다시 사용하려고 하면 비어 있게 됩니다.
def even_numbers(n):
for x in range(n):
if (x%2==0):
yield x
num = even_numbers(10)
for i in num:
print(i)
print("\n")
print("Calling the generator again: ", list(num))
출력
0
2
4
6
8
Calling the generator again: []
출력을 다시 사용하려면 함수를 다시 호출해야 합니다.
예 : 피보나치 시리즈의 제너레이터와 yield
다음 예제는 Python에서 제너레이터와 yield를 사용하는 방법을 보여줍니다. 예제는 피보나치 수열을 생성합니다.
def getFibonnaciSeries(num):
c1, c2 = 0, 1
count = 0
while count < num:
yield c1
c3 = c1 + c2
c1 = c2
c2 = c3
count += 1
fin = getFibonnaciSeries(7)
print(fin)
for i in fin:
print(i)
출력 :
<generator object getFibonnaciSeries at 0x000001F6B2E97748>
0
1
1
2
3
5
8
예: yield로 함수 호출
이 예제에서는 yield로 함수를 호출하는 방법을 볼 것입니다.
아래 예제에는 주어진 숫자의 제곱을 반환하는 test()라는 함수가 있습니다. yield 키워드와 함께 test()를 사용하는 getSquare()라는 또 다른 함수가 있습니다. 출력은 주어진 숫자 범위에 대한 제곱 값을 제공합니다.
def test(n):
return n*n
def getSquare(n):
for i in range(n):
yield test(i)
sq = getSquare(10)
for i in sq:
print(i)
출력:
0
1
4
9
16
25
36
49
64
81
Python에서 Return 대신 Yield를 사용해야 하는 경우
Python3 Yield 키워드는 호출자에게 제너레이터를 반환하고 제너레이터가 반복될 때만 코드 실행이 시작됩니다.
함수 의 반환 은 함수 실행의 끝이며 단일 값이 호출자에게 다시 제공됩니다.
다음은 Return 대신 Yield를 사용해야 하는 상황입니다.
- 데이터 크기가 클 때 return 대신 yield 사용
- 대용량 데이터 세트에서 더 빠르게 실행해야 할 때 Yield가 최선의 선택입니다.
- 호출하는 함수에 많은 값을 반환하려면 yield를 사용하세요.
- yield는 크거나 무한한 데이터를 생성하는 효율적인 방법입니다.
Yield vs. Return
Yield와 Return의 차이점은 다음과 같습니다.
Yield | Return |
Yield는 호출자에게 제너레이터 개체를 반환하고 제너레이터가 반복될 때만 코드 실행이 시작됩니다. | 함수의 반환은 함수 실행의 끝이며 단일 값이 호출자에게 다시 제공됩니다. |
함수가 호출되고 yield 키워드를 만나면 함수 실행이 중지됩니다. 생성자 객체를 호출자에게 다시 반환합니다. 함수 실행은 제너레이터 객체가 실행될 때만 시작됩니다. | 함수가 호출되면 실행이 시작되고 return 키워드가 있는 경우 값이 호출자에게 다시 제공됩니다. 함수 내부의 반환은 함수 실행의 끝을 표시합니다. |
yield expression | return expression |
yield 키워드를 사용하면 메모리가 사용되지 않습니다. | 반환된 값에 대해 메모리가 할당됩니다. |
메모리를 사용하지 않아 대용량 데이터를 처리해야 하는 경우 매우 유용합니다. | 매우 작은 데이터 크기에 편리합니다. |
데이터 크기가 큰 경우 yield 키워드를 사용하면 성능이 더 좋습니다. | 데이터 크기가 커서 성능을 저해하는 경우 많은 메모리가 사용됩니다. |
데이터 크기가 큰 경우 yield의 경우 실행 시간이 더 빠릅니다. | 데이터 크기가 큰 경우에 수행되는 추가 처리가 있기 때문에 사용되는 실행 시간이 더 길지만 작은 데이터 크기에서는 잘 작동합니다. |
요약 :
- 파이썬의 yield 키워드는 return처럼 작동하지만 유일한 차이점은 값을 반환하는 대신 호출자에게 제너레이터 함수를 반환한다는 것입니다.
- 제너레이터는 한 번 사용되면 다시 사용할 수 없는 특수한 유형의 반복기입니다. 값은 메모리에 저장되지 않으며 호출될 때만 사용할 수 있습니다.
- 제너레이터의 값은 for-in, list() 및 next() 메서드를 사용하여 읽을 수 있습니다.
- yield와 return의 주요 차이점은 yield는 제너레이터 함수를 호출자에게 반환하고 return은 호출자에게 단일 값을 제공한다는 것입니다.
- Yield는 어떤 값도 메모리에 저장하지 않으며, 어떤 값도 메모리에 저장되지 않아 데이터 크기가 클 때 유용하다는 장점이 있습니다.
- 큰 데이터 크기에 대한 return에 비해 yield 키워드를 사용하면 성능이 더 좋습니다.
'초보자를 위한 Python > 5. Python 함수' 카테고리의 다른 글
5.11 파이썬 컬렉션의 카운터(Counter) (0) | 2022.10.27 |
---|---|
5.10 파이썬 큐(Queue) : FIFO, LIFO 예제 (0) | 2022.10.26 |
5.8 예제가 있는 Python Timeit() (0) | 2022.10.24 |
5.7 예제가 있는 파이썬 map() 함수 (0) | 2022.10.13 |
5.6 파이썬 round() 함수 예제 (0) | 2022.10.11 |
댓글