Post

4주 - 함수

함수

함수 만들기

함수의 기본

함수 사용법

1
2
3
4
5
6
7
8
# def 함수이름(매개변수,매개변수2):
#     문장

def print_3_times(value,n):
    for i in range(n):
        print(value)

print_3_times("냐옹냐옹",3) #냐옹냐옹 3번 반복

def로 정의후 괄호안의 매개변수를 내부 문장에 전달하여 리턴값을 출력하여 사용한다.

주의점 : 함수에 정의했던 매개변수의 수가 적거나 많으면 타입에러가 발생합니다.

가변 매개변수

가변 매개변수를 활용하면 매개 변수를 원하는 만큼 사용할 수 있는 함수를 만들 수 있다.

1
2
3
4
5
6
7
8
# def 함수이름(매개변수,매개변수2,*가변매개변수):
#    문장
def print_3_times(n,*values):
    for i in range(n):
        for value in values:
            print(value)

print_3_times(3,"냐옹냐옹","혼공단","정한민")

 주의점

가변 매개변수 뒤에 일반 매개변수가 올수 없다

가변매개변수는 하나만 사용할 수 있다.

기본 매개변수

기본 매개변수 : “매개변수 = 값” 의 형태

매개변수를 입력하지 않아도 기본값으로 입력이 됨

1
2
3
4
5
6
7
8
# def 함수이름 (매개변수,가변매개변수, 기본 매개변수 순으로 사용)
#    문장
def print_n_times(*values, n=2):
    for i in range(n):
        for value in values:
            print(value)

print_n_times("냐옹냐옹","혼공단","정한민")

주의점 : 기본 매개변수 뒤에 일반 매개변수가 오면 안됨

키워드 매개변수

기본 매개변수가 가변 매개변수보다 앞에 올때

함수 사용시 매개변수가 순서대로 입력되기에 기본 매개변수의 의미가 사라짐

가변 매개변수가 기본 매개변수보다 앞에 올때

반대로 가변 매개변수가 앞에 오게되면 문제가 생김

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def print_n_times(*values, n=2):
    for i in range(n):
        for value in values:
            print(value)

print_n_times("냐옹냐옹","혼공단","정한민",3)

출력 
냐옹냐옹
혼공단
정한민
3
냐옹냐옹
혼공단
정한민
3

마지막 매개변수에 3이 입력되야하지만 가변매개변수로 들어가게됨

이를 막고자 키워드 매개변수를 사용함

키워드 매개변수

매개변수의 이름을 직접적으로 적용하여 사용함

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def print_n_times(*values, n=2):
    for i in range(n):
        for value in values:
            print(value)

print_n_times("냐옹냐옹","혼공단","정한민", n = 3)

출력 
냐옹냐옹
혼공단
정한민
냐옹냐옹
혼공단
정한민
냐옹냐옹
혼공단
정한민

가변 매개변수 중에서 필요한 값만 입력하기

원하는 값만을 직접적으로 컨트롤 할 수 있음

1
2
3
4
5
6
7
def test(a,b=10,c=100):
    print(a+b+c)

test(10,20,30) #60
test(a=10,b=100,c=200) #310
test(c=10,a=100,b=200) #310
test(10,c=200) #220

리턴

리턴값 : 함수의 결과 값을 뜻함

return : 함수를 실행했던 위치로 돌아가라는 키워드

자료값 없이 리턴해보기

1
2
3
4
5
6
def return_test():
    print("A위치")
    return
    print("B위치")

return_test() #A위치 출

함수 실행 후 return위치에서 바로 멈추고 함수 실행 종료됨

자료값 함께 리턴해보기

return 뒤에 값을 입력하면 같이 되돌아감

1
2
3
4
5
def return_test():
    return 100

value = return_test()
print(value) #100 출력

아무것도 없이 리턴해보기

1
2
3
4
5
def return_test():
    return 

value = return_test()
print(value) #None출력됨

아무런 값이 없기에 None이 출력되는걸 확인할 수 있다.

기본적인 함수의 활용 방법

1
2
3
4
5
6
7
8
9
10
11
12
# def 함수(매개변수):
#     변수 = 초깃값
#     #여러가지 처리
#     return 변수

def sum_all(start=0, end=100, step=1):
    output = 0
    for i in range(start, end + 1, step):
        output += i
    return output

print("A.", sum_all(0, 100, 10)) # 550

함수의 활용

재귀함수

재귀함수란? : 내부에서 자기자신을 호출하는 함수

팩토리얼 계산에 필요한 n! = n (n-1) *(n-2)…..1 까지의 계산을 하기 위해

반복문을 통해 출력에 숫자를 곱함

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def factorial(n):
    output = 1
    for i in range(1, n + 1):
        output *= i
    return output

for i in range(1, 11):
    print(f"{i}!:", factorial(i)) 

1!: 1
2!: 2
3!: 6
4!: 24
5!: 120
6!: 720
7!: 5040
8!: 40320
9!: 362880
10!: 3628800

재귀함수를 이용하여 팩토리얼을 구하기

f(4) = 4 *f(3)

f(4) = 4 *3 *f(2)

f(4) = 4 *3 *2 *f(1)

f(4) = 4 *3 *2 * 1 *1

이런식으로 함수내부에 함수를 사용하여 구하는 방식

1
2
3
4
5
6
7
8
def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n - 1)

for i in range(1, 11):
    print(f"{i}!:", factorial(i))

문제점

재귀함수는 상황에 따라서 같은 계산을 기하급수적으로 많이 반복하게됩니다.

이를 해결하기 위해 메모화를 이용하여 계산 값을 저장하여 빠르게 계산함

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
dictionary = {
    1: 1,
    2: 1
}

def fibonacci(n):
    if n in dictionary:
        return dictionary[n]
    ele:
        output = fibonacci(n - 1) + fibonacci(n - 2)
        dictionary[n] = output
        return output

print("fibonacci(1):", fibonacci(1)) 
print("fibonacci(2):", fibonacci(2)) 
print("fibonacci(3):", fibonacci(3)) 
print("fibonacci(10):", fibonacci(10)) 

for key in dictionary.keys():
    value = dictionary[key]
    print(key, value)


fibonacci(1): 1
fibonacci(2): 1
fibonacci(3): 2
fibonacci(10): 55

딕셔너리 저장된  출력해보기
1 1
2 1
3 2
4 3
5 5
6 8
7 13
8 21
9 34
10 55

딕셔너리를 사용해서 한번 계산한 값들을 저장함(이를 메모 한다고 표현)

조기 리턴

함수 중간에 사용하여 들여쓰기 단계가 줄어들어 코드를 쉽게 읽을 수 있음

1
2
3
4
5
6
7
8
9
10
11
12
#조기리턴 X
def is_even(n):
    if n % 2 == 0:
        return True
    else:
        return False

#조기 리턴
def is_even(n):
    if n % 2 != 0:
        return False
    return True

리스트 평탄화하는 재귀함수 만들어보기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def flatten(data):
    output = []
    for item in data:
        if type(item) == list:
            output += flatten(item) 
        else:
            output.append(item)
    return output

example = [[1, 2, 3], [4, [5, 6]], 7, [8, 9]]
print("원본: ", example)
print("변환: ", flatten(example))

원본 : [[1, 2, 3], [4, [5, 6]], 7, [8, 9]]
변환 : [1, 2, 3, 4, 5, 6, 7, 8, 9]

파이썬 튜터

함수 고급

튜플

튜플 : 리스트와 비슷한 자료형, 한번 결정된 요소는 바꿀수 없다

1
2
3
4
5
6
7
8
# 사용법 튜플명 = (데이터,데이터,데이터)
tuple_test= (10,20,30)
tuple_test[0] #10
tuple_test[1] #20
tuple_test[2] #30

tuple_test[0] = 1
#타입 오류 발생 
튜플의 특징들

괄호 없이 사용할 수 있음

한 번에 여러 개를 쉽게 할당, 교환, 리턴할 수 있음

divmod 함수로 몫과 나머지를 한 번에 계산할 수 있음

요소가 하나일 경우, 요소 뒤에 컴마(,)를 작성해야 튜플로 인식함  예시 : (요소,)

괄호없는 튜플

1
2
3
4
5
6
7
8
9
tuple_test = 10, 20, 30, 40
print("tuple_test:", tuple_test) # tuple_test: (10, 20, 30, 40)
print("type(tuple_test):", type(tuple_test)) # type(tuple_test): <class 'tuple'>
print()

a, b, c = 10, 20, 30
print("a:", a) # a: 10
print("b:", b) # b: 20
print("c:", c) # c: 30

변수의 값을 교환가능

1
2
3
4
5
6
7
8
9
10
a, b = 10, 20
print("a:", a)
print("b:", b)
print()

a, b = b, a

print("a:", a)
print("b:", b)
print()

튜플과 함수

1
2
3
4
5
6
7
def test():
    return (10, 20)

a, b = test() # a, b = (10, 20)

print("a:", a) # 10
print("b:", b) # 20

람다

콜백함수

콜백함수 - 함수의 매개변수로 사용되는 함수

1
2
3
4
5
6
7
8
def call_10_times(func): #print_hello가 콜백으로 들어감
    for i in range(10):
        func()

def print_hello():
    print("안녕하세요")

call_10_times(print_hello)

함수를 매개변수로 사용하는 표준함수

map(), filter() 가 대표적임

map(함수, 리스트) : 리스트의 요소를 함수에 넣고 리턴값으로 새로운 리스트를 구성해줌

filter(함수, 리스트) : 리스트의 요소를 함수에 넣고 리턴값이 True인 것으로 새로운 리스트를 구성해줌

1
2
3
4
5
6
7
8
9
10
11
12
def power(item):
    return item * item
def under_3(item):
    return item < 3

list_input_a = [1, 2, 3, 4, 5]

output_a = map(power, list_input_a) #요소를 함수에 넣어서 계산후 리스트로 재구성
print("map(power, list_input_a):", list(output_a)) #[ 1, 4, 9, 16, 25] 제곱된 값이 리스트로 재구성됨

output_b = filter(under_3, list_input_a) #함수의 값이 True인 값만 리스트로 재구성
print("filter(under_3, list_input_a):", list(output_b)) # [1,2] 3미만의 값만 리스트로 재구성됨 

람다의 개념

간단한 함수를 쉽게 선언하는 방법

lambda 매개변수 : 리턴값

1
2
3
4
5
6
7
list_input_a = [1, 2, 3, 4, 5]

output_a = map(lambda x: x * x, list_input_a)
print("map(power, list_input_a):", list(output_a))

output_b = filter(lambda x: x < 3, list_input_a)
print("filter(under_3, list_input_a):", list(output_b))

콜백함수에 람다함수를 넣어서 바로 확인이 가능함

간단하게 쉽게 함수를 선언하게됨

파일 열고 닫기

파일 열때 : 파일객체 = open(문자열 : 파일경로 , 문자열 : 읽기모드)

파일 닫을때 : 파일객체.close

1
2
3
file = open("혼공단.txt", "w")
file.write("냐옹냐옹...!")
file.close()

또는 with키워드를 이용하여 열고 바로 닫게할수 있음

1
2
with open("혼공단.txt", "w") as file:
    file.write("냐옹냐옹...!")

텍스트 쓰기 w

1
2
3
4
with open("혼공단.txt", "w") as file:
    file.write("처음쓰는 냐옹냐옹...!") 

#처음쓰는 냐옹냐옹...!

텍스트 이어쓰기 a

1
2
3
4
with open("혼공단.txt", "") as file:
    file.write("냐옹냐옹...!") 

#처음쓰는 냐옹냐옹...!냐옹냐옹...!

마지막 뒷부분에 이어서 써짐

텍스트 읽기 r

1
2
3
4
5
with open("혼공단.txt", "r") as file:
    contents = file.read()
print(contents)

#처음쓰는 냐옹냐옹...!냐옹냐옹...!

제너레이터 함수

제너레이터 함수는 이터레이터를 직접 만들때 사용함

yield키워드를 사용하여 제너레이터 함수로 만들며

next()함수를 사용해 함수 내부코드를 실행함

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def test():
    print("A 지점 통과")
    yield 1
    print("B 지점 통과")
    yield 2
    print("C 지점 통과")

output = test()

print("D 지점 통과")
a = next(output)
print(a)

print("E 지점 통과")
b = next(output)
print(b)

print("F 지점 통과")
c = next(output)
print(c)

next(output)

제너레이터 객체는 실행때마다 조금씩 사용하여 메모리 효율성이 높다.

This post is licensed under CC BY 4.0 by the author.

Trending Tags