함수는 파이썬에 기본으로 포함되어 있는 내장 함수를 사용할 수도 있고, 프로그래머가 직접 정의하여 사용할 수도 있다.

함수를 직접 정의하는 법

#함수 정의
def 함수명 (매개 변수):
	실행할 문장들
    return 리턴 값
  

#함수 호출
함수명(인자)
   

이 때 매개변수와 리턴 값은 생략될 수도, 하나 이상이 될 수도 있다.

실습. 자판기 프로그램의 함수화

이전 자판기 프로그램의 코드에서 4개의 기능을 함수화 하시오.

  1. check_machine: 남은 음료수를 확인할 수 있는 함수
  2. is_drink: 해당 음료수가 남아있는지 확인하는 함수
  3. add_drink: 입력된 음료수를 추가하는 함수
  4. remove_drink: 입력된 음료수를 제거하는 함수

<내 코드>

#실습3. 자판기 프로그램 함수화

vending_machine = ['게토레이', '게토레이', '레쓰비', '레쓰비','생수', '생수', '생수', '이프로']

def check_machine():
     print("남은 음료수: ", vending_machine)

def is_drink(drink):
    return drink in vending_machine

def add_drink(drink):
    vending_machine.append(drink)
    vending_machine.sort()
    return vending_machine

def remove_drink(drink):
     vending_machine.remove(minus)
     return vending_machine
      


while True:     
    check_machine()
    #print("사용자 종류를 입력하세요(소비자일 경우 \'소비자\', 또는 숫자 1을, 주인일 경우 \'주인\' 또는 숫자 2를 입력해주세요): \n 1. 소비자 \n 2.주인 \n ")

    inning = input("\n사용자 종류를 입력하세요(소비자일 경우 \'소비자\', 또는 숫자 1을, 주인일 경우 \'주인\' 또는 숫자 2를 입력해주세요): \n 1. 소비자 \n 2.주인 \n 3. 종료 \n ")

    if inning == "1" or inning == "소비자":
        pur = input("마시고 싶은 음료수를 입력하세요: ")
        if is_drink(pur):
             print(f"{pur} 드릴게요.")
             vending_machine.remove(pur)
        else:
             print(f"{pur}은 지금 없네요.")
    elif inning == "2" or inning == "주인":
        inning2 = input("원하시는 기능을 선택해주세요. (추가를 원하실 경우 \'추가\' 또는 숫자 0을, 삭제를 원하실 경우 \'삭제\' 또는 숫자 1을 입력해주세요): \n 1. 추가 \n 2. 삭제 \n")
        if inning2 == "1" or inning2 == "추가":
            check_machine()
            plus = input("추가할 음료수를 입력해주세요.: ")
            add_drink(plus)
            check_machine()
        elif inning2 == "2" or inning2 == "삭제":
            check_machine()
            minus = input("삭제할 음료수를 입력해주세요: ")
            if is_drink(minus):
                print("삭제 완료")
                remove_drink(minus)
                check_machine()
            else:
                    print(f"자판기 안에 {minus}가(이) 없습니다. \n")
                    check_machine()
        else:
                print("잘못된 입력입니다. (추가를 원하실 경우 \'추가\' 또는 숫자 1을, 삭제를 원하실 경우 \'삭제\' 또는 숫자 2를 입력해주세요): ") 
    elif inning == '3' or inning == '종료':
         print("자판기 프로그램을 종료합니다.")
         break 
    else:
        print("잘못된 입력입니다. 소비자일 경우 '소비자', 또는 숫자 1을, 주인일 경우 '주인' 또는 숫자 2를 입력해주세요): ")

변수

전역 변수: 함수, 클래스 외부에 선언하고 영향 범위가 파일 전체
+) 값을 변경하지 않는 상수에 자주 사용된다.
지역 변수: 함수나 명령문(조건, 반복 등)의 블록 안에서 생성되며 블록 {}을 벗어나면 메모리에서 소멸
ex) 함수에 사용되는 매개변수도 지역변수라고 할 수 있다.

동일한 식별자가 지역 변수와 전역 변수로 동시에 존재할 경우:
지역 변수가 전역 변수보다 우위에 있음을 기억하자.

global 키워드

전역 변수를 함수 내에서 읽기만 하는 것은 가능하지만, 변경하는 것은 불가능하다.
-> global 키워드를 이용하면 가능하다!
ex)

x = 0

def oneUp():
	global x # 전역 변수 x에 접근하여 값 변경이 가능해짐
    x = x + 1
    return x

print(oneUp()) #1
print(oneUp()) #2
print(oneUp()) #3 

유의할 점:
-이 때 전역 변수가 리스트, 딕셔너리 등 값을 변경하더라도 같은 메모리 위치를 참조하는 변수라면, 함수 내부에서 전역 변수의 수정을 시도해도 오류가 발생하지 않는다.
-만약 변수가 숫자, 문자열, 튜플인 경우 값을 (변경 x) 재할당하면 새로운 메모리 위치를 참조하게 되기 때문에 global 키워드가 필요하게 된다.

매개변수

함수의 기본 매개변수

함수의 매개변수를 초기화하여 선언하고 함수 호출 시 인수를 생략하면 기존에 입력된 초기 값으로 출력된다.
ex) def 함수이름(변수1, 변수 2 = 상수):

함수의 매개변수는 순서가 중요하다. 인수를 일부 생략한 채 함수를 호출하면 함수 정의 시 먼저 적혀있던 매개변수의 순서대로 함수에 먼저 입력된다.
-> 그러나 이를 순서에 상관 없이 매개변수에 값을 전달하고 싶다면 함수 호출 키워드를 활용하면 된다.

함수 호출 키워드

함수 호출 시 매개 변수에 값을 전달할 때 매개변수의 이름을 지정하여 전달하는 방식
-> 순서와 상관 없이 값을 전달할 수 있다!

# 함수 호출 키워드
def intro(name, age, city):
    print(f"이름은 {name}이고 나이는 {age}이고 사는 곳은 {city}입니다.")

intro("홍길동", 23, "서울")
intro(city = "서울", name = "임꺽정", age = 23)
intro("홍길동", city = "부산", age = 25) 
#키워드 지정이 없는 매개 변수의 값을 먼저 입력할 것! 순서에 맞게 써야 한다.

함수의 가변 매개변수

-가변 위치 매개변수
-매개변수의 개수가 가변적일 때 식별자 앞에 *을 붙여 사용하며 관례상 *args 식별자를 사용
-모든 위치 매개변수를 튜플 형태(변형이 안 되는 리스트)로 묶어서 사용
+)가변 매개변수는 고정 위치 매개변수의 뒤에 있어야 한다.
ex)

def text_def(a, b, *args): #무조건 고정, 1:1 대응인 애들이 앞으로 가고 가변인 애들을 뒤로 빼줘야 한다!
    print("test :", a)
    print("test :", b)
    print("args :", args)

text_def("hi", 1,2,3,4,5) #튜플형태로 나온다

<출력 예시>
test : hi
test : 1
args : (2, 3, 4, 5)

함수의 가변 키워드 매개변수

-키워드의 개수가 가변적일 때 사용
-식별자 앞에 **을 표시하며 관례상 **kwargs 식별자를 사용
-모든 키워드 매개변수를 딕셔너리 형태로 묶어서 사용

주의) 반드시 고정 위치 매개변수 - 가변 위치 매개변수 - 가변 키워드 매개변수 순서대로 쓸 것.

ex)

def intro(**kwargs): #가변 키워드 매개변수
    for key, value in kwargs.items():
        print(f"{key}: {value}")

intro(name = "홍길동", age = 20, city = "Seoul", gender = "female" )

<출력 예시>
name: 홍길동
age: 20
city: Seoul
gender: female

내장함수

파이썬 내장함수 라이브러리 링크

<자주 쓰는 내장함수 예시>

abs(실수): 절댓값을 구하여 출력
pow(x, y): x의 y제곱
square(실수): 실수 제곱

내장함수 예제 - map()

map(함수, 반복 가능한 객체):
리스트의 각 요소에 주어진 함수를 적용하여 새로운 리스트를 반환
-> 결과를 list()로 꼭 변환시켜주어야 한다!

내장함수 예제 - filter()

filter(함수, 반복 가능한 객체):
이 때, filter() 안에 들어가는 함수는 True / False 값을 리턴하는 함수가 들어와야 한다.
-> 리스트에서 조건을 만족하는 요소만 필터링하여 반환한다.
-> 결과를 list()로 꼭 변환시켜주어야 한다!

<Tip> map()과 filter() 안에는 간단한 함수만 넣을 것!

실습. 배수 판별하는 함수 만들기

1 ~ 30의 자연수 중 특정 수의 배수와 배수의 개수를 계산하는 함수를 정의하시오.


#방법1 # filter() 이용하기
def count(num): #num의 배수로만 이루어진 리스트를 생성하여 반환한다.
    lists = [i for i in range(1, 31) if 1 % num == 0] 
    counts = len(lists)
    return lists, counts


num = 3
lists, counts = count(num)
print(f"{num}의 배수: {lists}")
print(f"{num}의 배수의 개수: {counts}")

#방법2

def count(num):
    #중첩 함수 - 함수 내에 또다른 함수를 정의한다. 이 함수 내에서만 사용이 가능
    def check(x): # 나머지가 0인지 True / False로 반환
        return x % num == 0
 
    lists = list(filter(check, range(1, 31)))
    return lists, len(lists)

num = 3
lists, counts = count(num)
print(f"{num}의 배수: {lists}")
print(f"{num}의 배수의 개수: {counts}")

재귀함수

함수 안에서 자기 자신을 호출하는 함수
->무한 반복하는 구조이기 때문에 종료 조건이 필요하다.
->반복적인 구조의 간결한 표현에 유리하다.

def func(입력값):
	if 조건 (입력값이 충분히 작으면): #종료 조건
    	return 결과값
    else: #더 작은 값으로 호출
    	return 결과값(func() 호출)

<대표적인 예시 2가지>

  1. 팩토리얼 연산
def factorial(n):
    print("n의 값:", n)
    if n == 1:
        return 1
    else:
        return n * factorial(n-1)

print(factorial(3))

결과 예시:
n의 값: 3
n의 값: 2
n의 값: 1
6

  1. 피보나치 수열
def fibonacci(num):
    if num == 0:
        return 0
    elif num == 1:
        return 1
    else:
        return fibonacci(num-1) + fibonacci(num-2)
    
print(fibonacci(6)) #8

+) 이 방식은 재귀함수의 개념을 설명하기에는 유용하나, 시간 복잡도를 고려한다면 그다지 효율적이지 못한 코딩이라고 한다. 참고해둘 것!

람다식(Lambda Expression)

-람다 함수(Lambda Function)는 짧은 익명함수를 작성할 때 사용.
-이름 없이 한 줄로 간단하게 정의할 수 있음.
-def와 return 등의 키워드를 생략한다. (애초에 return 값이 있는 함수이다.)
-변수인데 쓸 때는 함수처럼.

형식: lambda 매개변수: 표현식

<람다식의 활용 예시>

람다함수를 매개변수로 전달하기

def call(func): #매개변수로 함수를 받는 함수
    for _ in range(10):
        func()
        
#def 써서 일반적인 함수처럼 정의
def hello():
    print("안녕하세요")

#lambda 함수 써서 매개변수 없이 단순 한줄 출력을 하는 것이 더 적합하다.
hello2 = lambda: print("반갑습니다.")

call(hello)
call(hello2)

lambda 함수와 map()함수 함께 사용하기

numbers = [2, 4, 6, 8]
squared = map(lambda x : x ** 3, numbers)
print(list(squared))  #map()의 예시와 비교

lambda 함수와 filter()함수 함께 사용하기


numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(list(filter(lambda x: x % 2 ==0, numbers))) #filter()의 예시와 비교

0개의 댓글