def add(a, b): # a와 b가 매개변수
return a + b
인수 : 함수를 호출할 때 전달하는 값이나 변수add(10, 20) # 10과 20이 인수
함수에 인수를 순서대로 넣는 방식을 위치 인수(positional argument)라고 한다. 즉, 인수의 위치가 정해져 있다.
>>> print(10, 20, 30)
10 20 30
>>> def print_numbers(a, b, c):
... print(a)
... print(b)
... print(c)
>>> print_numbers(10, 20, 30)
10
20
30
인수를 순서대로 넣을 때는 리스트나 튜플을 사용할 수도 있다. 다음과 같이 리스트 또는 튜플 앞에 *(애스터리스크)를 붙여서 함수에 넣어주면 된다.
>>> x = [10, 20, 30]
>>> print_numbers(*x)
10
20
30
# 변수 대신 리스트 바로 앞에 붙여도 된다.
>>> print_numbers(*[10, 20, 30])
10
20
30
단, 이때 함수의 매개변수 개수와 리스트의 요소 개수는 같아야 한다.
위치 인수와 리스트 언패킹은 인수의 개수가 정해지지 않은 가변 인수(variable argument)에 사용한다. 즉, 같은 함수에 인수 한 개를 넣을 수도 있고, 열 개를 넣을 수도 있다. 또는, 인수를 넣지 않을 수도 있다.
가변 인수 함수는 매개변수 앞에 *를 붙여서 만든다.
>>> def print_numbers(*args):
... for arg in args:
... print(arg)
...
고정 인수와 가변 인수를 함께 사용할 때는 다음과 같이 고정 매개변수를 먼저 지정하고, 그 다음 매개변수에 *를 붙여주면 된다. 가변 인수가 고정 매개변수보다 앞쪽에 오면 안된다.
>> def print_numbers(a, *args): ... print(a) ... print(args) ... >> print_numbers(1) 1 () >> print_numbers(1, 10, 20) 1 (10, 20) >> print_numbers(*[10, 20, 30]) 10 (20, 30)
인수(매개변수)에 용도에 맞는 이름을 정한다.
함수(키워드=값)으로 호출할 수 있다.
이때 키워드 인수를 사용하면 인수의 순서를 맞추기 않아도 된다.
```
>>> def personal_info(name, age, address):
... print('이름: ', name)
... print('나이: ', age)
... print('주소: ', address)
...
>>> personal_info('홍길동', 30, '서울시 용산구 이촌동')
이름: 홍길동
나이: 30
주소: 서울시 용산구 이촌동
```
>>> personal_info(age=30, address='서울시 용산구 이촌동', name='홍길동')
이름: 홍길동
나이: 30
주소: 서울시 용산구 이촌동
print 함수에서 사용했던 sep, end도 키워드 인수다.
print(10, 20, 30, sep=':', end='')
함수를 호출할 때 키워드 인수로 직접 값을 넣었다. 이번에는 딕셔너리를 사용해서 키워드 인수로 값을 넣는 딕셔너리 언패킹을 사용해보겠다. 다음과 같이 딕셔너리 앞에 **(애스터리스크 두 개)를 붙여서 함수에 넣어준다.
>>> def personal_info(name, age, address):
... print('이름: ', name)
... print('나이: ', age)
... print('주소: ', address)
...
함수를 만든 후 딕셔너리에 '키워드': 값 형식으로 인수를 저장하고, 앞에 **를 붙여서 함수에 넣어준다. 이때 딕셔너리의 키워드(키)는 반드시 문자열 형태여야 한다.
>>> x = {'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'}
>>> personal_info(**x)
이름: 홍길동
나이: 30
주소: 서울시 용산구 이촌동
# 딕셔너리 변수 대신 딕셔너리 앞에 바로 **를 붙여도 동작은 같다.
>>> personal_info(**{'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'})
이름: 홍길동
나이: 30
주소: 서울시 용산구 이촌동
딕셔너리 언패킹을 사용할 때는 함수의 매개변수 이름과 딕셔너리의 키 이름이 같아야 한다. 매개변수 개수와 딕셔너리 키의 개수도 같아야 한다.
딕셔너리는 키-값 쌍 형태로 저장되어 있어 애스터리스크를 한 번 사용하면 키가 출력된다. 즉, 딕셔너리를 한 번 언패킹하면 키를 사용한다는 뜻이다. 따라서 애스터리스크를 두번 사용해 딕셔너리를 두 번 언패킹하여 값을 사용한다.
키워드 인수를 사용하는 가변 인수 함수는 매개변수 앞에 **를 붙여서 만든다.
아래는 값 여러 개를 받아서 매개변수 이름과 값을 각 줄에 출력하는 함수다. 함수를 만들 때 괄호 안에 **kwargs와 같이 매개변수 앞에 **를 붙인다. 함수 안에서는 for로 kwargs.items()를 반복하면서 print로 값을 출력한다.
>>> def personal_info(**kwargs):
... for kw, arg in kwargs.items():
... print(kw, ': ', arg, sep='')
...
>>> personal_info(name='홍길동')
name: 홍길동
>>> personal_info(name='홍길동', age=30, address='서울시 용산구 이촌동')
name: 홍길동
age: 30
address: 서울시 용산구 이촌동
# 위처럼 인수를 직접 넣어도 되고, 딕셔너리 언패킹을 사용해도 된다.
>>> x = {'name': '홍길동'}
>>> personal_info(**x)
name: 홍길동
>>> y = {'name': '홍길동', 'age': 30, 'address': '서울시 용산구 이촌동'}
>>> personal_info(**y)
name: 홍길동
age: 30
address: 서울시 용산구 이촌동
매개변수의 초깃값은 주로 사용하는 값이 있으면서 가끔 다른 값을 사용해야 할 때 활용한다. 대표적인 예가 print 함수인데, print 함수의 sep는 초깃값이 ' '(공백)으로 지정되어 있어서 대부분 그대로 사용하고, 가끔 sep에 다른 값을 넣어서 사용한다.
# 매개변수 address의 초깃값 지정
>>> def personal_info(name, age, address='비공개'):
... print('이름: ', name)
... print('나이: ', age)
... print('주소: ', address)
# 실행 결과
# address는 초깃값이 있으므로 personal_info는 다음과 같이 address 부분을 비워 두고 호출할 수 있다.
>>> personal_info('홍길동', 30)
이름: 홍길동
나이: 30
주소: 비공개
# 매개변수에 초깃값이 지정되어 있더라도 값을 넣으면 해당 값이 전달된다.
>>> personal_info('홍길동', 30, '서울시 용산구 이촌동')
이름: 홍길동
나이: 30
주소: 서울시 용산구 이촌동
초깃값이 지정된 매개변수 다음에는 초깃값이 없는 매개변수가 올 수 없다. 초깃값이 지정된 매개변수는 뒤쪽에 몰아주면 된다.
def personal_info(name, age, address='비공개'):
def personal_info(name, age=0, address='비공개'):
def personal_info(name='비공개', age=0, address='비공개'):
korean, english, mathematics, science = map(int, input().split())
def get_min_max_score(*args):
return min(args),max(args)
def get_average(**kwargs):
return (sum(kwargs.values()))/len(kwargs)
min_score, max_score = get_min_max_score(korean, english, mathematics, science)
average_score = get_average(korean=korean, english=english,
mathematics=mathematics, science=science)
print('낮은 점수: {0:.2f}, 높은 점수: {1:.2f}, 평균 점수: {2:.2f}'
.format(min_score, max_score, average_score))
min_score, max_score = get_min_max_score(english, science)
average_score = get_average(english=english, science=science)
print('낮은 점수: {0:.2f}, 높은 점수: {1:.2f}, 평균 점수: {2:.2f}'
.format(min_score, max_score, average_score))
get_min_max_score 함수는 get_min_max_score(korean, english, mathematics, science)처럼 인수를 위치 인수로 넣고 있으므로 def get_min_max_score(*args):와 같이 만들어준다.
get_average 함수는 get_average(korean=korean, english=english, mathematics=mathematics, science=science)처럼 인수를 키워드 인수로 넣고 있으므로 def get_average(**kwargs):와 같이 만들어준다. 함수 안에서는 평균을 구해야 하는데 먼저 sum(kwargs.values())처럼 values로 딕셔너리의 값만 가져온 뒤 sum으로 합계를 구한다.
함수 안에서 함수 자기자신을 호출하는 방식을 재귀호출(recursive call)이라고 한다.
def hello():
print('Hello, world!')
hello()
hello()
실행해보면 'Hello, world!' 문자열이 계속 출력되다가 에러가 발생한다. 파이썬에서는 최대 재귀 깊이(maximum recursion depth)가 1,000으로 정해져 있어서 hello 함수가 자기자신을 계속 호출하다가 최대 재귀 깊이를 초과하면 RecursionError가 발생한다.
def hello(count):
if count == 0: # 종료 조건을 만듦. count가 0이면 다시 hello 함수를 호출하지 않고 끝냄
return
print('Hello, world!', count)
count -= 1 # count를 1 감소시킨 뒤
hello(count) # 다시 hello에 넣음
hello(5) # hello 함수 호출
#실행결과
Hello, world! 5
Hello, world! 4
Hello, world! 3
Hello, world! 2
Hello, world! 1
팩토리얼은 1부터 n까지 양의 정수를 차례대로 곱한 값이며 !(느낌표) 기호로 표기한다. 예를 들어 5!은 5 4 3 2 1이며 결과는 120이다.
재귀호출은 반환값이 중요하다. 반환값이 없으면 무한정 돌다 에러 발생
def factorial(n):
if n == 1: # n이 1일 때
return 1 # 1을 반환하고 재귀호출을 끝냄
return n * factorial(n - 1) # n과 factorial 함수에 n - 1을 넣어서 반환된 값을 곱함
print(factorial(5))
마지막 1이 반환됨으로써 1이 상위 값들과 연산하며 최종값이 다시 반환된다.
https://dojang.io/mod/page/view.php?id=2355
```
def is_palindrome(word):
if len(word) < 2: # 문자가 두 개 미만이면 True반환. 종료
return True
if word[0] != word[-1]: # 제일 바깥쪽 문자열 쌍 비교
return False
return is_palindrome(word[1:-1]) # 밖에서 두번째 문자열 쌍까지만
# (제일 바깥쪽 문자열 쌍 제외) 잘라서 다시 비교
print(is_palindrome('hello'))
print(is_palindrome('level'))
#실행 결과
False
True
```
if len(word) < 2:는 if word[0] != word[-1]:보다 먼저 와야 한다. 그렇지 않으면 글자가 하나도 없는데도 word[0]과 word[-1]에 접근하여 에러가 발생하게 된다.
https://dojang.io/mod/quiz/review.php?attempt=1154493&cmid=2356
피보나치 수열 : 바로 앞의 두 피보나치 수의 합
반환값 1이 나올 때까지 계속 돈다.