본 포스팅은 책 「두근두근 파이썬」을 참고하여 공부한 내용의 정리본입니다.
이전 게시글
두근두근 파이썬 Chapter 4 함수와 입출력 (1)
2021/01/13 - [Programming/#Python] - [Python] 두근두근 파이썬 Chapter 4 함수와 입출력 (1) (실습 결과 포함)
0. 들어가며
이전 포스팅에서는 함수를 정의하고 호출하는 방법과, 함수 호출 시 실제 값을 전달 받는 '매개변수', 그리고 매개변수에 할당되는 실제 값인 '인자'에 대해 다루었다. 더불어, return 키워드를 사용하여 결과를 반환하는 방법과 지역변수, 전역 변수의 사용법에 대해서도 알아보았다. 이어서 이번 포스팅에서는 인자의 여러 가지 전달 방식에 대해 다루고, 함수 내부에서 자기 자신을 호출하는 함수인 재귀함수, 그리고 입/출력 함수를 포함한 여러가지 메소드를 응용해보기로 한다.
1. 함수의 인자 전달 방식
함수를 호출할 때, 인자를 빠뜨리는 경우 오류가 발생한다. 이를 미연에 방지하기 위해 인자의 디폴트 매개변수 (default parameter)를 지정해줄 수 있다. 이렇게 되면 인자를 입력하지 않더라도 에러 없이 함수가 수행되므로 좀 더 유연한 작업이 가능하다.
>>> def print_star(n = 1): for _ in range(n): print('*********************') >>> print_star() # 인자 없이 출력 *********************
같은 함수에 대하여 이번엔 인자를 2로 지정해보자. 이 경우 함수는 인자로서 디폴트 매개변수 대신 2를 인자 값으로 취한다.
>>> print_star(2) # n = 1은 수행되지 않음 ********************* *********************
반면, 2개의 매개변수를 갖는 함수에 대해 둘 중 하나의 매개변수만 디폴트 값을 지정해주는 것도 가능하다.
>>> def div(a, b = 2): return a / b >>> print('div(4) =', div(4)) # 두 번째 인자는 생략 >>> print('div(6) =', div(6)) div(4) = 2.0 div(6) = 3.0
위와 같이 마지막 인자 값을 생략해주는 작업은 가능하지만, 아래와 같이 첫 번째 매개 변수에 디폴트 값을 할당하고 인자 값을 따로 지정해주지 않는 작업은 불가능하다. 즉, 디폴트 매개변수는 전체 변수에 대해 할당하거나 나중에 출현하는 변수부터 할당해야 한다는 규칙이 있다.
>>> def div(a = 2, b): return a / b SyntaxError: non-default argument follows default argument # 전체 변수에 디폴트 값을 할당하는 경우 >>> def div(a = 1, b = 2): return a / b >>> print('div() =', div()) # div(1, 2) >>> print('div(4) =', div(4)) # div(4, 2) >>> print('div(6, 3) =', div(6, 3)) # div(6, 3) div() = 0.5 div(4) = 2.0 div(6, 3) = 2.0
2. 키워드 인자 (keyword argument)
키워드 인자란 함수 호출 시 인자 값과 더불어 해당 인자의 이름을 함께 명시하는 방식이다. 기본적으로 파이썬에서 인자를 전달하는 방식은 아래와 같은 위치 인자 (positional argument) 방식을 따른다.
>>> def get_root(a, b, c): r1 = (-b + (b ** 2 - 4 * a * c) ** 0.5) / (2 * a) r2 = (-b - (b ** 2 - 4 * a * c) ** 0.5) / (2 * a) return r1, r2 >>> result1, result2 = get_root(1, 2, -8) >>> print('해는', result1, '또는', result2) 해는 2.0 또는 -4.0 >>> result1, result2 = get_root(-8, 2, 1) >>> print('해는', result1, '또는', result2) 해는 -0.25 또는 0.5 # 다른 결과
반면, 인자를 할당할 때, a, b, c의 키워드를 통해 값을 전달할 변수명을 명시해주면 인자의 순서에 따라 결과 값이 변하지 않는다.
>>> result1, result2 = get_root(a = 1, c = -8, b = 2) 해는 2.0 또는 -4.0 >>> result1, result2 = get_root(c = -8, b = 2, a = 1) 해는 2.0 또는 -4.0
이와 같이 키워드 방식으로 인자를 전달할 때는 몇 가지 유의할 사항이 있다. 만일, 키워드 인자와 위치 인자를 혼용하는 경우에는 위치인자를 먼저 표현해야 한다.
다음은 키워드 인자와 위치 인자의 잘못된 혼용으로 발생하는 오류의 예시다.
>>> result1, result2 = get_root(c = -8, b = 2, 1) SyntaxError: positional argument follows keyword argument >>> result1, result2 = get_root(1, -8, b = 2) TypeError: get_root() got multiple values for argument 'b' >>> def func(a, b, c): print(a, b, c) >>> func(1, 2, 3) 1 2 3 >>> func(1, c=2, b=3) 1 3 2 >>> func(1, b=2, 3) SyntaxError: positional argument follows keyword argument
지금까지 다룬 키워드, 위치 인자를 응용하여 사각형, 원의 면적을 구하는 함수를 구현해보면 다음과 같다.
>>> def func(shape, width = 1, height = 1, radius = 1): if shape == 0: return width * height if shape == 1: return 3.14 * radius ** 2 >>> print("rect area =", func(0, width = 10, height = 2)) >>> print("circle area =", func(1, radius = 5)) rect area = 20 circle area = 78.5
위의 func() 함수는 shape이 0일 때는 사각형의 면적을, 1일 때는 원의 면적을 계산하는데, width, height, radius의 디폴트 값이 할당되어 있기 때문에 논리 오류의 여지가 있다.
>>> print("rect area =", func(0, radius=5)) # 논리 오류 rect area = 1 # width, height는 디폴트 값인 1, 1로 계산됨 >>> print("circle area =", func(1, radius =5)) circle area = 78.5
LAB 4-9: 키워드 인자
# 문항 1-(a) >>> def print_name(honorifics, first_name, last_name): print(honorifics, first_name, last_name) >>> print_name(first_name = 'Gildong', last_name = 'Hong', honorifics = 'Dr.') Dr. Gildong Hong # 문항 1-(b) >>> print_name('Gildong', 'Hong', 'Dr.') Gildong Hong Dr.
3. 가변적인 인자 전달
가변 인자(arbitrary argument)란 인자의 수가 정해져 있지 않은 인자를 말한다. 함수를 표현할 때는 별표(*)를 매개 변수 앞에 넣어 사용하며, for-in 구문에서 리스트, 튜플과 유사하게 사용할 수 있다.
>>> def greet(*names): for name in names: print('안녕하세요', name, '씨') >>> greet('홍길순', '홍길동', '이순신') # 3개의 인자 >>> greet('Luna', 'Thomas') # 2개의 인자 안녕하세요 홍길순 씨 안녕하세요 홍길동 씨 안녕하세요 이순신 씨 안녕하세요 Luna 씨 안녕하세요 Thomas 씨
이때, 가변 인자의 길이를 알고 싶다면 함수 내부에서 len() 함수를 이용하여 인자의 개수를 출력할 수 있다.
>>> def foo(*args): print('인자의 개수:', len(args)) print('인자들:', args) >>> foo(10, 20, 30) 인자의 개수: 3 인자들: (10, 20, 30) # 가변 인자의 각 값은 튜플 형식으로 반환됨
LAB 4-10: 가변 인자의 활용
# 문항 1 >>> def sum_nums(*numbers): result = 0 for n in numbers: result += n avg = result / len(numbers) print('합계:', result, '평균:', avg) >>> sum_nums(10, 20, 30) 합계: 60 평균: 20.0 >>> sum_nums(10, 20, 30, 40, 50) 합계: 150 평균: 30.0 # 문항 2 >>> def min_nums(*inte): minimum = min(inte) print('최솟값은', minimum) >>> min_nums(20, 40, 50, 10) 최솟값은 10
4. 재귀함수 (recursion)
재귀함수란 함수 내부에서 자기 자신을 호출하는 함수를 말한다. 이러한 재귀함수를 이용하면 복잡한 문제를 직관적이고 간단하게 해결할 수 있다.
팩토리얼
팩토리얼은 n * (n-1)!로 정의할 수 있다. 이에 따라 factorial(n) 함수는 재귀적으로 프로그램을 구현하였다.
>>> def factorial(n): if n <= 1: return 1 else: return n * factorial(n-1) # n * (n-1)! >>> n =5 >>> print('{}! = {}'.format(n, factorial(n)) 5! = 120
피보나치 수
피보나치 수열은 다음과 같이 정의된다.
>>> def fibonacci(n): if n <= 1: return n else: return(fibonacci(n-1) + fibonacci(n-2)) # 정의에 입각 >>> nterms = int(input('몇 개의 피보나치수를 원하세요?')) >>> if nterms <= 0: print('오류: 양수를 입력하세요.') else: print('Fibonacci 수열:', end = '') for i in range(nterms): print(fibonacci(i), end = ' ') 몇 개의 피보나치수를 원하세요? 10 Fibonacci 수열:0 1 1 2 3 5 8 13 21 34
5. 입력함수와 출력함수
input() 함수
input() 함수는 사용자로부터 값을 입력받는 기능을 한다.
>>> print('Enter your name:') Enter your name: Jiwon >>> name = input() # 사용자가 입력한 값을 참조함 >>> print('Hello', name, '!') Hello Jiwon !
input() 함수와 int() 함수
아래 예제와 같이, 덧셈 연산은 동일 자료형끼리만 가능하다. 이에 따라 자료형의 변환이 필요한 경우가 발생하는데, 이때 int() 함수는 인자의 자료형을 정수형으로, float() 함수는 실수형으로, str() 함수는 문자열 형으로 형 변환시켜준다.
>>> 100 + 1 # 숫자 + 숫자 101 >>> '100' + '1' # 문자 + 문자 (연결) '1001' >>> '100' + 1 # 문자 + 숫자 (오류) TypeError: must be str, not int >>> int('100') + 1 101 >>> float('100') + 1 101.0 >>> num1 = int(input('숫자를 입력하세요:')) 숫자를 입력하세요: 100 >>> print(num1) 100
split() 메소드
input() 함수를 통해 2개의 값을 입력받고자 할 때, 다음과 같이 split() 메소드를 사용할 수 있다. 이 경우, 공백을 기준으로 문자열을 2개로 나누어주었으며, 각각을 s1, s2에 할당한 모습이다.
>>> s1, s2 = input('문자열 2개를 입력하세요:').split() # 동시할당 문자열 2개를 입력하세요: Hello Python >>> s1 'Hello' '' >>> s2 'Python'
input() 함수는 기본적으로 입력 값을 문자열로 취급하기 때문에, split() 메소드를 활용하여 정수형 다중 입력을 받고 싶다면 int() 함수를 사용하여 다음과 같이 형변환해주어야 한다.
>>> num1, num2, num3 = input('세 정수를 입력하세요:').split() 세 정수를 입력하세요: 100 200 300 # 공백 기준 split >>> num1, num2, num3 = int(num1), int(num2), int(num3) # 사후적 형변환 >>> num1, num2, num3 (100, 200, 300)
이후에 다루겠지만, map() 메소드를 활용하여 다음과 같이 다중 입력을 받아줄 수도 있다.
>>> num1, num2, num3 = map(int, input('세 정수를 입력하세요:').split()) 세 정수를 입력하세요: 100 200 300 >>> num1, num2, num3 (100, 200, 300)
만일, 구분자 (separator)를 공백 대신 쉼표를 사용하고 싶다면 다음과 같이 구현할 수 있다.
>>> num1, num2, num3 = map(int, input('세 정수를 ,로 구분하여 입력하세요:').split(,)) 세 정수를 ,로 구분하여 입력하세요: 100,200,300 >>> num1, num2, num3 (100, 200, 300)
다음 게시글
두근두근 파이썬 Chapter 4 함수와 입출력 (fin)
2021/01/11 - [Programming/#Python] - [Python] 두근두근 파이썬 Chapter 4 함수와 입출력 (fin) (실습 결과 포함)
I'm a Senior Student in Data Science !
데이터 사이언스를 공부하고 있는 4학년 학부생의 TIL 블로그입니다. 게시글이 도움 되셨다면 구독과 좋아요 :)
'Programming > #Python' 카테고리의 다른 글
[Python] 모듈과 활용 (1) (실습 결과 포함) (0) | 2021.01.23 |
---|---|
[Python] 함수와 입출력 (fin) (실습 결과 포함) (0) | 2021.01.17 |
[Python] 함수와 입출력 (1) (실습 결과 포함) (0) | 2021.01.13 |
[Python] 제어문 (fin) (실습 결과 포함) (0) | 2021.01.12 |
[Python] 제어문 (2) (실습 결과 포함) (0) | 2021.01.11 |