함수다! 레벨업 하는 소리가 들린다.
그리고 이제서야 알게된건데.. velog 작성할때 나는 한줄에 br 하나만 인정이 되는줄 알았는데 한줄에 여러개를 같이 써도 되네 ㅎㅎㅎㅎ;; 괜히 엔터치느라 손가락 고생했다ㅠ
함수 : 식별자 뒤에 괄호가 붙어있는 상태 / "코드의 집합"
함수 호출하기 = 함수를 사용하는 것
매개변수 = 괄호 안에 있는 여러가지 자료
리턴값 = 함수를 호출해서 최종적으로 나오는 결과
def 함수 이름():
문장
def 함수 이름(매개변수, 매개변수, ...):
문장
TypeError: print_n_times() missing 1 required positional argument: 'n'
def print_n_times(value, n): #두개의 매개변수 지정 for i in range(n): print(value) print_n_times('안녕하세요') #매개변수로 하나만 넣었다.
TypeError: print_n_times() takes 2 positional arguments but 3 were given
def print_n_times(value, n): #두개의 매개변수 지정 for i in range(n): print(value) print_n_times('안녕하세요',10, 20) #매개변수로 세개를 넣었다.
print()함수와 같이 매개변수를 원하는 만큼 받을 수 있는 것 / 매개변수가 변할 수 있음을 의미한다
def 함수 이름(매개변수, 매개변수, ..., *가변 매개변수):
문장
가변 매개변수 사용 제약
def EX(n, *values):
#n번 반복하기
for i in range(n):
# values는 리스트처럼 활용 가능하다.
for value in values:
print(value)
# 함수 호출하기
EX(2, '안녕하세요', '즐거운', '파이썬') #values 안에 들어오는 세가지 값들
->
안녕하세요
즐거운
파이썬
안녕하세요
즐거운
파이썬
'매개변수 = 값' 의 형태로 존재
사용 제약
def EX(value, n=2):
#n 번 반복한다.
for i in range(n):
print(value)
# 함수 호출하기
EX('안녕하세요')
->
안녕하세요
안녕하세요
n값을 입력하지 않을 경우 기본값이 2로 들어가 두번 반복 출력되었다.
기본 매개변수가 가변 매개변수보다 앞에 올때는 기본 매개변수의 이미가 사라진다.
def EX(n=2, *values):
#n번 반복
for i in range(n):
# values는 리스트처럼 활용된다.
for value in values:
print(value)
# 함수 호출
EX('안녕하세요', '즐거운', '파이썬')
->
...
TypeError: 'str' object cannot be interpreted as an integer
안녕하세요가 n에 들어가고 즐거운, 파이썬이 values에 들어가게 되는데 range()의 매개변수로는 정수만 올 수 있으므로 에러 발생!
def EX(*values, n=2):
#n번 반복
for i in range(n):
# values는 리스트처럼 활용된다.
for value in values:
print(value)
# 함수 호출
EX('안녕하세요', '즐거운', '파이썬', 3)
->
...
TypeError: 'str' object cannot be interpreted as an integer
예상되는 출력 형태
1. ['안녕하세요', '즐거운', '파이썬']을 세번 출력
2. ['안녕하세요', '즐거운', '파이썬', 3]을 두번 출력
실행 결과
안녕하세요
즐거운
파이썬
3
안녕하세요
즐거운
파이썬
3
"흠.. 두개를 같이 쓰는 방법은 없나?"
"?? : 왜 없어!! 키워드 매개변수를 사용해봐!!"
매개변수 이름을 직접적으로 지정해서 값을 입력한다!
def EX(*values, n=2):
for i in range(n):
for value in values:
print(value)
# 함수 호출
EX('안녕하세요', '즐거운', '파이썬', n=3)
->
안녕하세요
즐거운
파이썬
안녕하세요
즐거운
파이썬
안녕하세요
즐거운
파이썬
+) while문 공부할때 비슷한 사례 있었음
while True:
# "."를 출력한다
# 기본적으로 end가 "\n"이라 줄바꿈이 일어나는데
# 빈 문자열 ""로 바꿔 줄바꿈이 일어나지 않게 한다.
print(".", end="") # 여기서 end=""가 키워드 매개변수 이다.
def test(a, b=10, c=100):
print(a+b+c)
# 1) 기본 형태
test(10, 20, 30) -> 60
# 2) 키워드 매개변수로 모든 매개변수를 지정한 형태
test(a=10, b=100, c=200) -> 310
# 3) 키워드 매개변수로 모든 매개변수를 마구잡이로 지정한 형태
test(c=10, a=100, b=200) -> 310
# 4-1) 키워드 매개변수로 일부 매개변수만 지정한 형태
test(10, c=200) -> 220
# 4-2)
test(c=200, 10) -> SyntaxError: positional argument follows keyword argument
결론 : 일반적으로 '일반 매개변수'는 필수로, 순서에 맞게 입력하면 된다. '기본 매개변수'는 필요한 것만 키워드를 지정해서 입력하는 경우가 많다.
input() = 함수를 실행하고 나면 함수값을 받는것
리턴값 = 위와 같은 함수의 결과
# inpu() 함수의 리턴값을 변수에 저장한다.
value = input('> ')
#출력하기
print(value)
+) 함수 내부에서는 return이라는 키워드 사용 가능하다.
def return_test():
print('A위치입니다.')
return
print('B위치입니다.')
return_test()
->
A 위치입니다.
함수 내부에서 출력을 두번 사용! 그런데 중간에 return이 존재한다. return은
1. 함수를 실행했던 위치로 돌아가라
2. 함수를 여기서 끝내라
라는 의미를 갖고 있으므로 'A위치입니다.'만 출력된 후 프로그램이 종료된다.
def return_test():
return 100
#함수 호출
value = return_test()
print(value)
->
100
리턴 뒤에 자료를 입력하면 자료를 가지고 리턴한다.
위 코드에서는 return 뒤에 100을 입력했으므로 결과적으로 100이 출력되었다.
def return_test():
return
#함수 호출
value = return_test()
print(value)
->
None
파이썬에서 None은 아무것도 없다라는 뜻이다.
def 함수(매개변수):
변수 = 초깃값
# 여러가지 처리
# 여러가지 처리
# 여러가지 처리
return 변수
내부에서 자기 자신을 호출하는 함수
n! = n (n-1) (n-2) ... 1
반복문 ver.
def factorial(n): output = 1 #초기값은 1. 어떤 값이라도 1을 곱하면 변화가 없기 때문이다. for i in range(1, n+1): output *= i return output print('1!:', factorial(1)) print('3!:', factorial(3)) -> 1!: 1 3!: 6
재귀함수 ver 1.
def factorial(n): if n == 0: return 1 else: return n * factorial(n-1) print('1!:', factorial(1)) print('3!:', factorial(3)) -> 1!: 1 3!: 6
ex) 토끼의 번식
-->
재귀함수 ver 1.
def fibonacci(n): if n == 1: rturn 1 if n == : return 1 else: return fibonacci(n-1) + fibonacci(n-2) print("fibonacci(1):", fibonacci(1)) print("fibonacci(2):", fibonacci(2)) print("fibonacci(3):", fibonacci(3)) print("fibonacci(4):", fibonacci(4)) -> fibonacci(1): 1 fibonacci(2): 1 fibonacci(3): 2 fibonacci(4): 3
재귀함수 ver 2. 속 들여다 보기 (함수 반복 횟수 파악용)
counter = 0 #변수 선언 def fibonacci(n): #어떤 피보나치 수를 구하는지 출력. print('fibonacci({})를 구합니다.'.format(n)) global counter counter += 1 #피보나치 수 구하기 if n == 1: return 1 if n == 2: return 1 else: return fibonacci(n-1)+fibonacci(n-2) #함수 호출 fibonacci(10) print('---') print('fibonacci(10) 계산에 활용된 덧셈 횟수는 {}번입니다.".format(counter)) -> fibonacci(10)를 구합니다. fibonacci(9)를 구합니다. ... fibonacci(1)를 구합니다. fibonacci(2)를 구합니다. --- fibonacci(10) 계산에 활용된 덧셈 횟수는 109번 입니다.
위와 같이 피보나치 수열 10번 반복하는데 109번 코드가 돌아간다.
재귀 함수는 상황에 따라서 같은 것을 기하습구적으로 많이 반복한다는 문제가 있다! (그래서 개발자 사이에서는 재귀 함수를 지양하자는 의견도 있다고 한다)
파이선은 함수 내부에서 함수 외부에 잇는 변수를 참조하지 못한다!! 피보나치수열의 재귀함수 ver 2. 코드에서 "global counter" 부분을 지우면 UnboundlocalError: local variable 'counter' referenced before assignmen 라는 에러가 뜬다.
변수에 접근하는 것을 참조라고 한다. 함수 내부에서 함수 외부에 잇는 변수라는 것을 서령하려면 아래와 같은 구문을 사용해야 한다.
global 변수 이름
재귀함수의 기하급수적 숫자로 반복되는 현상으로 해 사용을 기피한다! 이를 해결하려면?? --> 같은 값을 한번만 계산하도록 코드를 수정!!
# 메모 변수 만들기
dictionary = {
1: 1,
2: 2
}
#함수 선언
def fibonacci(n):
if n in dictionary:
#메모가 되어 있으면 메모된 값을 리턴
return dictionary[n]
else:
# 메모가 되어 있지 않으면 값을 구함
output = fibonacci(n-1) + fibonacci(n-2)
dictionary[n] = output
return output
print('fibonacci(10):', fibonacci(10))
print('fibonacci(20):', fibonacci(20))
print('fibonacci(30):', fibonacci(30))
->
fibonacci(10): 89
fibonacci(20): 10946
fibonacci(30): 1346269
딕셔너리를 이용해 한번 계산한 값을 저장!! 이를 메모한다고 표현한다.
딕셔너리에 값이 메모되어 있으면 처리를 수행하지 안혹 곧바로 메모된 값을 돌려주면서 코드의 속도를 빠르게 만들어준다.
과거와 달리 필요할 때 리턴을 하면 된다는 인식!
과거 : 변수는 반드시 앞쪽에 몰아서, 리턴은 제일 마지막에
def fibonacci(n): if n in dictionary: # 메모되어 있으면 메모된 값을 리턴 return dictionary[n] else: # 메모되어 있지 않으면 값을 구함 output = fibonacci(n-1) + fibonacci(n-2) dictionary[n] = output return output
요즘 : 필요할때 리턴하기
def fibonacci(n): if n in dictioanry: # 메모되어 있으면 메모된 값을 리턴 return dictionary[n] # 메모되어 있지 않으면 값을 구함 output = fibonacci(n-1) + fibonacci(n-2) dictionary[n] = output return output
위 같은 변화로 들여쓰기 단계가 줄어 가독성을 높일 수 있다!
흐름 중간에 return 키워드를 사용하는 것을 조기 리턴 이라 한다.