Day5. 함수

0ㅑ채
|2024. 1. 8. 17:34

 

 

A. 함수의 정의와 호출

함수는 한마디로 호출의 집합이다.

def 함수 이름():
    문장
def print_n_times(value, n):
    for i in range(n):
        print(value)
        
print_n_times("안녕하세요", 5)

안녕하세요
안녕하세요
안녕하세요
안녕하세요
안녕하세요

 

 

가변 매개변수

  • 매개변수를 원하는 만큼 입력할 수 있는 함수 (매개변수의 개수가 변할 수 있다.)
  • 가변 매개변수 뒤에는 일반 매개변수가 올 수 없다.
  • 가변 매개변수는 하나만 사용할 수 있다.
def print_n_times(n, *values):
    #n번 반복합니다.
    for i in range(n):
        #values는 리스트처럼 활용합니다.
        for value in values:
            print(value)
            print()
            
print_n_times(2, "안녕하세요", "뚱쌤", "배고파요")

안녕하세요

뚱쌤

배고파요

안녕하세요

뚱쌤

배고파요

 

 

기본 매개변수

  • 일반 매개변수(n), 기본 매개변수(n=2)
  • 기본 매개변수 뒤에는 일반 매개변수가 올 수 없다.
def print_n_times(value, n=2):
    for i in range(n):
        print(value)
        
print_n_times("안녕하세요", 3)

안녕하세요

안녕하세요

안녕하세요

 

 

가변 매개변수가 기본 매개변수보다 앞에 오면, 어디까지가 values에 해당하는지 알 수가 없다.

def print_n_times(*values, n=2):
    for i in range(n):
        for value in values:
            print(value)
        print()        
print_n_times("오늘", "점심은", "마라탕", 3)

오늘
점심은
마라탕
3

오늘
점심은
마라탕
3

 

 

키워드 매개변수

  • 이러한 문제를 해결하기 위해 등장
  • 매개변수 이름을 직접적으로 지정해서 값을 입력한다.
  • ex. end=""
def print_n_times(*values, n=2):
    for i in range(n):
        for value in values:
            print(value)
        print()        
print_n_times("오늘", "점심은", "마라탕", n=3)

 

 

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

def test(a, b=10, c=100): #함수헤더
    print(a+b+c) #함수 바디

#기본형태
test(10, 20, 30)
#키워드 매개변수로 모든 매개변수를 지정한 상태
test(a=10, b=100, c=200)
# 키워드 매개변수로 모든 매개변수를 마구잡이로 지정한 형태
test(c=10, a=100, b=200)
# 키워드 매개변수로 일부 매개변수만 지정한 형태
test(10, c=200)

60
310
310
220

 

 

리턴 return

def 함수 이름():   #함수 헤더
    문장                 #함수 바디
  • 함수를 호출한 부분에 함수 바디에서 작업한 부분을 반환하는 장치
  • 함수의 바디 부분에 [ return + 식 ]을 써주면 바디에서 수행된 결과를 호출한 곳으로 반환시킨다.
def return_test():
    print("A 위치입니다.")
    return
    print("B 위치입니다.")

print(return_test())

A 위치입니다.
None

  • return이 시행되면 호출한 곳으로 돌아간다.
  • 따라서 5번 문장은 시행되지 않는다. 이것을 사문이라고 한다. (필요없는 사족 문장)

 

자료와 함께 리턴하기

def return_test():
    return 100       #얘도 식이다. 상수 100.

value = return_test()
print(value)

100

def return_test():
    return 100+100

value = return_test()
print(value)

200

def return_test(num1, num2):
    return num1 + 100

value = return_test(10, 20)
print(value)
  • return num1 + 100이 수행됐을 때
  • 호출한 지점인 return_test(10, 20)에 return 식의 결과가 호출되고
  • value에 이 결과가 할당되는 메커니즘!

 

아무것도 리턴하지 않기

def return_test():
    return 

value = return_test()
print(value)

None

  • None은 없다는 뜻!

 

 

기본적인 함수의 활용

def 함수(매개변수):   
      변수=초깃값   
       # 여러가지 처리   
       # 여러가지 처리   
       # 여러가지 처리   
       return 변수
def sum_all(start, end):
    output = 0
    for i in range(start, end+1):
        output += i
    return output
    
print("0 to 100:", sum_all(0, 100))
print("0 to 1000:", sum_all(0, 1000))
print("50 to 100:", sum_all(50, 100))
print("500 to 1000:", sum_all(500, 1000))

0 to 100: 5050
0 to 1000: 500500
50 to 100: 3825
500 to 1000: 375750

 

기본 매개변수 사용하기

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))
print("B:", sum_all(end=100))
print("C:", sum_all(end=100, step=2))

A: 550
B: 5050
C: 2550

 

 

 

B. 함수의 활용

재귀함수

팩토리얼 구하기

  • n! = n * (n-1) * (n-2) * ... * 1
  • 반복문으로 구하기
def factorial(n):
    output = 1
    for i in range(1, n+1):
        output *= i
    return output

print("1!:", factorial(1))
print("2!:", factorial(2))
print("3!:", factorial(3))
print("4!:", factorial(4))
print("5!:", factorial(5))

1!: 1
2!: 2
3!: 6
4!: 24
5!: 120

 

  • 재귀함수로 구하기
def factorial(n):
    if n==0:
        return 1
    else:
        return n * factorial(n-1) #함수호출

print("1!:", factorial(1))
print("2!:", factorial(2))
print("3!:", factorial(3))
print("4!:", factorial(4))
print("5!:", factorial(5))

1!: 1
2!: 2
3!: 6
4!: 24
5!: 120

  • n=2일 때, return식에서는
    • 2 * factorial(2-1)
    • = 2 * factorial(1)
    • = 2 * 1
  • 따라서 2가 반환된다.

 

조기 리턴

  • return은 원래 함수 흐름의 끝에 써줘야 한다는 암묵적 룰이 있었는데
  • 요즘은 필요할 때 사용하면 된다는 주의. 옳고 그름은 없고 융통성 있게!
  • 이렇게 흐름중간에 return 키워드를 사용하는 것을 조기 리턴이라고 한다.

 

리스트 평탄화

[[1, 2, 3], [4, [5, 6]], 7, [8, 9]]  ▷  [1, 2, 3, 4, 5, 6, 7, 8, 9]

 

 

 

p.310

가독성은 프로그래밍에 굉장히 중요한 요소다.

주석을 잘 사용하는 사람이 프로그래밍을 잘하는 사람이다.

 

 

 

 

 

C. 함수 고급

튜플

(데이터, 데이터, 데이터, ...)

#튜플 선언
tuple_test = (10, 20, 30)

print(tuple_test[0]) #10
print(tuple_test[1]) #20
print(tuple_test[2]) #30

tuple_test[0] = 1 #오류!!
  • 튜플은 내부 요소 변경이 불가능하기 때문에 오류 발생
#괄호가 없는 튜플
tuple_test = 10, 20, 30, 40
print("tuple_test:", tuple_test)
print("type(tuple_test):", type(tuple_test))
print()

#괄호가 없는 튜플 활용
a, b, c = 10, 20, 30
print("a:", a)
print("b:", b)
print("c:", c)

tuple_test: (10, 20, 30, 40)
type(tuple_test): <class 'tuple'>

a: 10
b: 20
c: 30

 

튜플 할당

https://ko.from-locals.com/python-multi-variables-values/

# a, b = 100, 200, 300
# ValueError: too many values to unpack (expected 2)

# a, b, c = 100, 200
# ValueError: not enough values to unpack (expected 3, got 2)
a, *b = 100, 200, 300

print(a) # 100
print(type(a)) # <class 'int'>

print(b) # [200, 300]
print(type(b)) # <class 'list'>
  • 리스트로 저장이 가능하다.
*a, b = 100, 200, 300

print(a) # [100, 200] 
print(type(a)) # <class 'list'>

print(b) # 300
print(type(b)) # <class 'int'>

 

 

튜플 값 맞바꿈

a, b = 10, 20

print("# 교환 전 값")
print("a:", a)
print("b:", b)
print()

a, b, = b, a

print("# 교환 후 값")
print("a:", a)
print("b:", b)
print()

# 교환 전 값
a: 10
b: 20

# 교환 후 값
a: 20
b: 10

 

튜플과 함수

#함수 선언
def test():
    return (10, 20)

a, b = test()

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

a: 10
b: 20

#함수 선언
def test():
    return (10, 20)

a, b = test()

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

a: 10
<class 'int'>
b: 20
<class 'int'>

#함수 선언
def test():
    return (10, 20)

num = test()
print(type(num))

print("a:", num[0])
print("b:", num[1])

<class 'tuple'>
a: 10
b: 20

  • num = test() 이 문장은 
  • num = (10, 20) 과 같다.

 

함수의 매개변수로 함수 전달하기

# 매개변수로 받은 함수를 10번 호출하는 함수
def call_10_times(func):
    print(type(func))
    for i in range(3):
        func()
        
# 간단한 출력하는 함수
def print_hello():
    print("안녕하세요")
    
# 조합하기
call_10_times(print_hello)

print(type(print_hello))
  • func 함수는 정의되지 않았다. 
  • print_hello 함수를 인수로 사용했더니
  • 매개변수에 선언한 func가 이 형식을 할당받았다.
  • func = print_hello
  • 이걸 오버라이드라고 한다!

안녕하세요
안녕하세요
안녕하세요

<class 'function'>

 

 

filter() 함수와 map() 함수

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

map(함수, 리스트)
filter(함수, 리스트)
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() 함수의 실행결과")
print("map(power, list_input_a):", output_a)
print("map(power, list_input_a):", list(output_a))

output_b = filter(under_3, list_input_a)
print("# filter() 함수의 실행결과")
print("filter(power, list_input_a):", output_b)
print("filter(power, list_input_a):", list(output_b))

# map() 함수의 실행결과
map(power, list_input_a): <map object at 0x0000028F61ECAB00>      
map(power, list_input_a): [1, 4, 9, 16, 25]
# filter() 함수의 실행결과
filter(power, list_input_a): <filter object at 0x0000028F61ECAC80>
filter(power, list_input_a): [1, 2]

  • 3이상이면 False, 3미만이면 Flase
  • 결과로 나오는 <map object>와 <filter object>는 제너레이터다. 

람다

  • lambda 매개변수: 리턴값
#일반 함수 사용
def power(item):
    return item * item
def under_3(item):
    return item < 3

#람다 함수 정의할 때 사용
power = lambda x: x * x
under_3 = lambda x: x < 3

#람다 함수 호출할 때 사용
output_a = map(lambda x: x*x)
output_b = filter(lambda x: x<3, list_input_a)

 

 

 

파일 열고 닫기

open() 함수

  • 파일 열기
  • 파일 객체 = open(문자열: 파일 경로, 문자열: 읽기 모드)
  • 첫 번째 인수에는 파일 경로 입력, 두 번째 인수에는 모드를 지정

* write모드: 존재하지 않는 파일을 새로 만들 때

* append모드: 존재하는 파일에 add on할 떄

 

close() 함수

  • 파일을 닫을 때 
file = open("basic.txt", "w")

file.write("baedalsikyo")

file.close()

 

with 키워드

  • 파일을 열고 닫지 않는 실수를 방지하기 위해 사용
  • with 구문이 종료될 때 자동으로 파일이 닫힌다.

 

텍스트 읽기

read() 함수

with open("basic.txt", "r") as file:
    contents = file.read()
print(contents)

 

랜덤으로 1000명 키와 몸무게 만들기

# 랜덤한 숫자를 만들기 위해 가져온다.
import random

#간단한 한글 리스트를 만든다.
hanguls = list("가나다라마바사아자차카타파하")

#파일을 쓰기 모드로 연다.
with open("info.txt", "w") as file:
    for i in range(1000):
        #랜덥한 값으로 변수를 생성한다.
        name = random.choice(hanguls) + random.choice(hanguls)
        weight = random.randrange(40, 100)
        height = random.randrange(140, 200)
        #텍스트를 쓴다. 
        file.write("{}, {}, {}\n".format(name, weight, height))

 

'Python' 카테고리의 다른 글

Day7. 웹프로그래밍 개요  (1) 2024.01.18
Day6. 객체지향 프로그래밍  (0) 2024.01.16
Day4. 딕셔너리와 반복문  (1) 2024.01.05
Day3. 조건문과 리스트  (2) 2024.01.04
Day2. 변수와 함수, 연산자  (1) 2024.01.03