2.6 파이썬 함수

함수(function)는 입력을 받아 그 입력에 해당하는 출력을 반환(return)하는 기계와 같다. 예를 들어 500원을 넣으면 생수가 나오고, 1000원을 넣으면 콜라가 나오는 자판기는 다음과 같은 함수이다.

f(500) = "생수"
f(1000) = "콜라"

파이썬에는 def 키워드와 return 키워드를 사용하여 다음과 같이 함수를 만들 수 있다. 파이썬에는 def 키워드와 return 키워드를 사용하여 다음과 같이 함수를 만들 수 있다

def 함수이름(입력변수이름):
   출력변수를 만드는 명령
   return 출력변수이름
   

예를 들어 숫자 x를 입력하면 두 배가 되도록 하는 함수는 다음과 같다.

def twotimes(x):
    y = 2 * x
    return y

이렇게 만들어진 함수를 사용하려면 함수 이름과 그 뒤에 괄호로 싸인 입력값을 넣으면 된다.

twotimes(2)
4
twotimes(10)
20

연습 문제 2.6.1

  1. 짝수가 입력되면 짝수라는 문자열을, 홀수가 입력되면 홀수라는 문자열을 반환하는 함수를 만든다.

  2. 윤년을 나타나는 수가 입력되면 윤년이라는 문자열을, 그렇지 않은 수가 입력되면 평년이라는 문자열을 반환하는 함수를 만든다.

연습 문제 2.6.2

평년일 때 1, 3, 5, 7, 8, 10, 12 월은 31일, 4, 6, 9, 11월은 30일, 2월은 28일이다. 월을 나타내는 숫자를 입력하면 그 달의 날짜 수를 반환하는 함수 days1 를 만든다. 사용 예는 다음과 같다.

>>> days1(11) # 11월의 날짜 수
30

입력이 여러 개인 함수

함수의 입력은 한 개가 아니라 여러 개가 되어도 상관없다. 입력 변수가 여러개이면 쉼표, 영어로 comma 를 사용하여 함수를 정의한다. 입력 변수는 원하는 만큼 얼마든지 만들 수 있다.

def 함수이름(입력변수1, 입력변수2, 입력변수3):
   출력변수를 만드는 명령
   return 출력변수이름
def add(x, y):
    return x + y
add(1, 2)
3
def sum(a, b, c):
    s = a + b + c
    return s
sum(1, 2, 3)
6

연습 문제 2.6.3

연도를 나타내는 숫자와 월을 나타내는 숫자를 입력하면 그 달의 날짜 수를 반환하는 함수 days2 를 만든다.

사용 예는 다음과 같다.

>>> days2(2015, 1)
31

람다 함수

함수에 이름을 주지 않거나 코드를 짧게 줄여쓰는 방법으로 람다(lambda)함수라는 것이 있다. 예를 들어 다음 함수 f

def f(x):
    return 2 * x

람다 함수로 정의하면 다음과 같다.

f = lambda x : 2 * x
f(2)
4

람다 함수는 함수 자체를 다른 함수의 인수로 넣을 때, 함수의 출력값을 함수로 받을 때 유용하게 사용된다.

지역 변수

함수에 넣은 입력 변수나 함수 안에서 만들어진 변수는 함수 바깥에서는 사용할 수 없다. 혹시 이름이 같은 변수가 있다고 하더라도 별개의 변수가 된다.

따라서 함수 안에서 만들어지고 사용되는 함수를 지역 변수, 영어로 local variable 이라고 한다.

실제로 확인해 보자. 일단 함수 바깥에 혹시라도 y라는 변수가 있으면 del 명령으로 지운다.

del y
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-11-aa8f3401fc42> in <module>
----> 1 del y

NameError: name 'y' is not defined

기존에 y라는 변수가 없었으면 그런 변수가 없다는 오류가 나온다. 만약 기존에 y라는 변수가 있었으면 오류가 출력되지 않고 지워지기만 한다

이제 다음과 같이 y라는 이름의 지역 변수를 가지는 함수를 만들고 실행시킨다.

def f(x):
    y = 10 * x
    print("y = ", y)
    return y
f(10)
y =  100
100

y라는 변수가 생겨났는지 다시 확인한다.

y
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-14-9063a9f0e032> in <module>
----> 1 y

NameError: name 'y' is not defined

함수 안에서 만든 y라는 변수는 함수 밖에는 생성되지 않았다.

이번에는 함수 바깥에서 y라는 변수를 사용해 보자.

y = 1000
y
1000

이제 함수를 실행시킨다.

f(1)
y =  10
10

다시 바깥에서 y값을 확인하면 이전과 같다.

y
1000

즉, 함수 안에서 만들어지는 지역 변수는 함수 바깥에 아무런 영향을 주지 않는다.

연습 문제 2.6.4

3개의 숫자를 입력하면 “그 숫자들의 합”과 “그 숫자들을 제곱한 숫자들의 합”의 차이(큰 수에서 작을 수를 뺀 값)를 계산하는 함수 diffsum를 만든다. 큰 수에서 작은 수를 뺀 결과이므로 항상 0보다 크거나 0과 같아야 한다.

전역 변수

하지만 지역 변수와 반대로 함수 바깥에서 만들어진 변수는 함수 안에서 사용할 수 있다. 이러한 변수를 전역 변수(global variable)이라고 한다.

z = 3

def f2(x):
    y = z * x
    print("y =", y)
    print("z =", z)
    return y
f2(10)
y = 30
z = 3
30

다만, 이때 바깥의 변수와 같은 이름의 변수를 함수 안에 만들면 안 된다. 만약 바깥의 변수와 같은 이름의 변수를 함수 안에 다시 만들면 함수 안에서는 그 지역 변수를 사용하다가 함수 바깥으로 나오면 지역 변수는 사라지고 원래의 변숫값으로 되돌아온다. 따라서 함수 안에서는 함수 바깥에 있는 변수의 값을 바꿀 수 없다.

z = 3

def f3(x):
    z = 99
    y = z * x
    print("y =", y)
    print("z =", z)
    return y
f3(10)
y = 990
z = 99
990

함수 바깥에서는 z가 여전히 3이다.

z
3

만약 함수안에서 함수 바깥에 있는 변수의 값을 꼭 바꿔야만 한다면 다음과 같이 함수 이름 앞에 global 키워드를 선언해 주면 된다.

z = 3

def f4(x):
    global z
    z = 99
    y = z * x
    print("y =", y)
    print("z =", z)
    return y
f4(10)
y = 990
z = 99
990
z
99

함수 바깥의 z 값이 99로 바뀌어 있는 것을 확인할 수 있다.

연습 문제 2.6.5

함수 바깥에 m 이라는 전역 변수를 만들고 그 값을 0으로 놓는다. 앞에서 만든 diffsum 함수를 고쳐서 diffsum 함수와 같은 값을 반환하지만 함수를 실행할 때 마다 diffsum 함수에서 계산된 값이 원래 있던 m보다 크면 m을 계산된 값으로 바꾸는 함수 diffsum2 를 만든다.