다중 리턴 함수
함수 하나에서 값 여러 개 리턴받기
def mul_return(x):
y1 = x * 10
y2 = x * 100
y3 = x * 1000
return y1, y2, y3
val1, val2, val3 = mul_return(10)
print(val1, val2, val3)
100 1000 10000
이때 리턴하는 값은 정수형 데이터다.
리턴하는 값 수만큼 변수를 지정하지 않으면 튜플 형태로 리턴한다.
val = mul_return(10)
print(val)
(100, 1000, 10000)
리턴 자료형을 지정할 수도 있다.
def mul_return_list(x):
y1 = x * 10
y2 = x * 100
y3 = x * 1000
return [y1, y2, y3]
mul_return_list(10)
[100, 1000, 10000]
가변인자
함수가 받는 인자 수가 고정되지 않았을 때 사용한다.
가변인자 형태를 어떻게 지정하느냐에 따라 받을 수 있는 매개변수 형태가 달라진다.
*args
def args_func(*args):
print(args)
for i in args:
print(i)
인자를 하나(‘apple’)만 전달할 수도 있고
args_func('apple')
('apple',) # print(args)
apple # for문 내부 print(i)
두 개 이상을 전달할 수도 있다.
args_func('pineapple', 'watermelon', 'kiwi')
('pineapple', 'watermelon', 'kiwi')
pineapple
watermelon
kiwi
enumerate()
함수를 이용하면 다중 리턴값에 인덱스 번호를 매겨 활용할 수 있다.
def args_enumerate_func(*args):
for idx, value in enumerate(args):
print(idx, value)
args_func('banana', 'kiwi')
0 banana
1 kiwi
**kwargs
딕셔너리 자료형도 인자로 받을 수 있다.
def kwargs_func(**kwargs):
print(kwargs)
for key, value in kwargs.items():
print(key, value)
kwargs_func(name1='A')
{'name1': 'A'} # print(kwargs)
name1 A # for 문 내부 print(key, value)
kwargs_func(name1='A', name2='B', name3='C')
{'name1': 'A', 'name2': 'B'}
name1 A
name2 B
만약 *args를 인자로 받는 함수에 딕셔너리 자료형을 인자로 넘기거나, **kwargs를 인자로 받는 함수에 단일 값을 인자로 넘긴다면 TypeError가 발생한다.
args_func(fruit1='apple')
TypeError: args_func() got an unexpected keyword argument 'fruit1'
kwargs_func('A')
TypeError: kwargs_func() takes 0 positional arguments but 1 was given
*args, **kwargs를 모두 인자로 받는 함수
단 순서는 반드시 단일 인자 다음에 *args, 그 다음에 **kwargs를 둬야 한다.
def args_kwargs_func(arg1, arg2, *args, **kwargs):
print(arg1, arg2, args, kwargs)
args_kwargs_func(1, 2, 'Kang', 'Cha', age1=20, age2=24)
1 2 ('Kang', 'Cha'), {'age1': 20, 'age2': 24}
중첩함수 (클로저)
def nested_func(num):
def func_in_func(num):
print(num)
print('in func')
func_in_func(num + 10000)
nested_func(10000)
in func
20000
리턴 순서를 보면 func_in_func
함수 안에 있는 print문은 건너뛴 것을 알 수 있다.
def nested_func(num):
def func_in_func(num):
print(num) # 3. 마지막에 실행
print('in func') # 1. 가장 먼저 실행
func_in_func(num + 10000) # 2. 그 다음 실행
nested_func
함수 호출 후 func_in_func
에서 바로 인자를 넘겨받지만 실제 func_in_func
함수 실행은 nested_func
내 다른 코드를 순차로 실행하면서 실행된다.
함수에 힌트 주기
def mul3(x: int) -> list:
y1 = x * 10
y2 = x * 100
y3 = x * 1000
return [y1, y2, y3]
라는 것은 int형 인자를 넘겨야하고, 리턴값 형태는 list라는 뜻이다. 힌트를 줘서 좀 더 친절한 코드로 만들 수 있다.
lambda
람다식을 사용하면 메모리를 절약할 수 있고, 가독성 높은 간결한 코드를 작성할 수 있다. 하지만 남용하면 오히려 가독성이 떨어지니 필요한 곳에만 사용해야 한다.
일반 함수 vs. 람다식
- 일반 함수: 객체 생성 -> 리소스(메모리) 할당
- 람다식: 즉시 실행(Heap 초기화) -> 메모리 초기화
일반 함수를 선언해보자.
def mul_10(x):
return x * 10
mul_10_func = mul_10
print(mul_10_func)
<function mul_10 at 0x7f81e002c940>
함수를 선언하니 객체가 생성되었다. 객체가 생성되었다는 것은 메모리가 할당되었다는 뜻이다.
람다식 사용법
lambda_mul_10 = lambda x: x * 10
print(lambda_mul_10(10))
100
함수를 인자로 받는 함수를 만들어서 람다식을 인자로 넘겨줄 수도 있다.
def lambda_ex(x, y, func):
print(x * y * func(10))
lambda_ex(10, 10, lambda_mul_10)
10000 # 10 * 10 * (10*10)
혹은 람다식을 바로 만들어서 넘길 수 있다.
lambda_ex(10, 10, lambda x: x * 100)
100000 # 10 * 10 * (100 * 10)