Python에서 보통의 함수는 값을 반환하고 종료하지만 Generators 함수는 값을 반환하기는 하지만 산출(yield)한다는 차이점이 있습니다. 그리고 Generator는 Iterator를 생성해주는 함수라고도 볼 수 있습니다.
def generator_squares():
for i in range(3):
yield i ** 2
print("gen object=", end=""), print(generator_squares())
gen object=<generator object generator_squares at 0x10f3b0150>
yield
는 제너레이터 함수에서 값을 반환할 때 사용되며 yield
호출 후에 다시 next
가 호출될 때 까지 현재 상태에서 머물고 있다가 next
함수가 호출되면 이전 상태에 이어서 다음 연산을 수행합니다.
gen = generator_squares()
print(gen.__next__())
print(gen.__next__())
print(gen.__next__())
print(gen.__next__())
출력결과
0
1
4
Traceback (most recent call last):
File "generator.py", line 14, in <module>
print(gen.__next__())
StopIteration
Iterator 처럼 Iter()
를 호출한 후에 Next()
함수를 호출 하지 않아도 Next()
를 바로 호출할 수 있습니다. 또한 for 문이 끝나면 StopIteration이 발생합니다.
Generator 함수는 실행 중 Send()
함수를 통해서 값을 전달할 수 있습니다.
def generator_send():
received_value = 0
while True:
received_value = yield
print("received_value = ",end=""), print(received_value)
yield received_value * 2
gen = generator_send()
next(gen)
print(gen.send(2))
next(gen)
print(gen.send(3))
출력결과
received_value = 2
4
received_value = 3
6
generator_send 함수는 yield
로 send
를 통해 값을 전달하여received_value에 값을 할당할 수 있습니다.
제너레이터 함수의 모든 값이 메모리에 저장되어 있는게 아닌 호출 될 때마다 값을 하나씩 메모리에 저장되기 때문에 메모리 용량에 효율적이다.
Lazy Evaluation이란 계산의 결과값이 필요할 때까지 계산을 늦추는 기법으로 실행을 지연시킨다는 의미입니다.
제너레이터 표현식(Generator Expression)은 List Comprehension 문법과 비슷하지만 대괄호([]
)가 아닌 괄호(()
)를 사용하여 만듭니다.
import time
def print_iter(iter):
for element in iter:
print(element)
def lazy_return(num):
print("sleep 1s")
time.sleep(1)
return num
print("comprehension_list=")
comprehension_list = [ lazy_return(i) for i in L ]
print_iter(comprehension_list)
print("generator_exp=")
generator_exp = ( lazy_return(i) for i in L )
print_iter(generator_exp)
comprehension_list =
sleep 1s
sleep 1s
sleep 1s
1
2
3
generator_exp =
sleep 1s
1
sleep 1s
2
sleep 1s
3
List Comprehension은 미리 return_lazy 함수를 미리 실행하여
comprehension_list
값을 만들어 놓고 한번에 return으로 값을 출력한다.
Lazy Evaluation은 generator_exp 함수를 사용하는 순간에만 값을 출력한다.
Lambda는 인라인 함수를 정의할 때 사용되며 익명 함수(Anonymous Functions) 또는 람다 표현식(Lambda Expression)이라고 부릅니다.
일반함수
def name(arg1, arg2 ...):
block of statement
Lambda
lambda argument1, argument2, ... argumentN : expression using arguments
일반 함수와 Lambda의 차이점은 이름의 유무, 인라인 형식의 간단한 표현식으로 return 문 없이도 표현식의 결과가 리턴됩니다.
인라인 콜백함수를 만들거나 함수안에서 복잡한 처리를 할 수 없을 때 유용하다고 할 수 있습니다.
(콜백함수 : 어떤 이벤트가 발생했을 때 호출되는 함수)
def square(x):
return x ** 2
def power_3(x):
return x ** 3
def power_4(x):
return x ** 4
powers = [ square, power_3, power_4 ]
for f in powers:
print( f(2) )
Lambda 사용 할 경우
Lambdas = [
lambda x : x ** 2,
lambda x : x ** 3,
lambda x : x ** 4
]
for lambda_func in Lambdas:
print( lambda_func(2) )
어떤 정수에 2제곱, 3제곱 등.. 제곱하는 예제를 함수로 구현한 것보다 람다 함수가 사용되는 위치에 인라인 표현식으로 사용한 코드가 깔끔해집니다.