본문 바로가기

Python

12. 함수( 반환값, 매개변수, 람다함수, filter(), map())

1. 함수의 반환값


함수의 반환값
- return 값|변수|식
- return 문 아래의 명령은 수행되지 않는다.
- return 값을 쉼표를 이용해서 튜플형태로 내보내기 할 수 있다. 

- 세 수의 모든 합을 반환하는 함수 정의
- 매개변수 O, 반환값 O 함수 정의
def calculate()


# - 세 수의 모든 합을 반환하는 함수 정의
# - 매개변수 O, 반환값 O 함수 정의
def calculate( x, y, z) :
    total = x+y+z
    # return 반환값이 없다면 None
    return f' {x} + {y} + {z} = {total} ' 
print(calculate( 10, 20, 30))  # 10 + 20 + 30 = 60

# - return 뒤의 반환값이 여러개인 경우
# - 세 수의 모든 합과 차을 반환하는 함수 정의
# - 매개변수 O, 반환값 O 함수 정의
def calculate2( x, y, z) :
    total1 = f'{x} + {y} + {z} = {x+y+z}'
    total2 = f'{x} - {y} - {z} = {x-y-z}'
    return total1, total2 # 쉼표를 이용한 반환값

# 변수에 함수를 호출해서 저장
result = calculate2(10, 20, 50)
print(type(result), result)
print(result[0])
print(result[1])

결과

<class 'tuple'> ('10 + 20 + 50 = 80', '10 - 20 - 50 = -60')
10 + 20 + 50 = 80
10 - 20 - 50 = -60

# - 세 수의 모든 곱을 반환하는 함수 정의
# - 매개변수 O, 반환값 O 함수 정의 ( print() 있는 경우 )
def calculate3( x, y, z) :
    total = x*y*z
    # 반환할때 print() 이용
    return print(f' {x}X{y}X{z} = {total} ')

print('-'*10)

# 함수 호출1
calculate3(3, 4, 5)   
결과)
3X4X5 = 60
  
print('-'*10)

# print() 문안에 함수 호출2
print(calculate3(3, 4, 5))

결과)
  
3X4X5 = 60
None

왜? 프린트문 안에서 프린트를 호출 했기 때문에 None 출력

2. 매개변수

 

'''
매개변수의 초기값
매개변수 모두에 초기값이 있는 경우


def 함수명(매개변수1=값1, 매개변수2=값2, ... ) :
    명령문


매개변수 일부분만 초기값이 있는 경우
:

** 초기값이 없는 매개변수는 앞으로 배치 
** 초기값이 있는 매개변수는 뒤로 배치
def 함수명(매개변수1, 매개변수2=값2, ... ) :
    명령문
    
    
def calculate4( x=1, y=1, z=1) :
    total = x*y*z
    return print(f' {x}X{y}X{z} = {total} ')


# 함수 호출 테스트
print('-'*30)
calculate4() # 1X1X1 = 1
calculate4(10) # 10X1X1 = 10
calculate4(10, 20) # 10X20X1 = 200
calculate4(10, 20, 30) # 10X20X30 = 6000

print('-'*30)
# 매개변수 일부에만 초기값이 있는 경우
def calculate5( x, y=1, z=1) :
# def calculate5( x=1, y, z=1) : 이런 식으로 표현하면 Error / 초기값이 있는건 뒤로 밀어야 한다.
    total = x*y*z
    return print(f' {x}X{y}X{z} = {total} ')
calculate5(2,3,4) # 2X3X4 = 24
calculate5(2,3) #2X3X1 = 6
calculate5(2) #2X1X1 = 2
calculate5() #TypeError

'''


'''
Quiz

아래의 함수를 호출하여 메세지가 출력되도록 함수를 정의하여라

# 함수 정의
def say_myself(name, old, man=True):

풀이)

def say_myself(name, old, man=True) :
    print(f'나의 이름은 {name} 입니다. ')
    print(f'나이는 {old}살 입니다.')
    if man :
        print("남자입니다.")
    else :
        print("여자입니다.")    

say_myself('김철수', 20)
say_myself('이민정', 15, False)

결과)

나의 이름은 김철수 입니다. 
나이는 20살입니다.
남자입니다.

나의 이름은 이민정 입니다.
나이는 15살입니다.
여자입니다.

'''
# 가변매개변수
'''
- 매개변수가 튜플형태로 함수안에서 사용
- 매개변수의 갯수가 정해지지 않은 경우에 사용


def 함수명(*매개변수명):
    명령문
    return 반환값
    
- 일반 매개변수와 가변 매개변수가 함께 쓰인 경우
 : 가변 매개변수는 뒤에 배치
def 함수명(매개변수1, *매개변수명2):
    명령문
    return 반환값

'''

# 매개변수가 가변인 경우
def multy1(*args) :
    # 함수 내부에서는 아스테리크(*) 없이 사용
    print(args, type(args))
    if args: # 데이터 갯수가 0이 아니면 데이터 출력
        for item in args:
            print(item)
    else : print('데이터가 없습니다....')
    print('-'*10)   
   
multy1()
# () <class 'tuple'>
# 데이터가 없습니다....
multy1('강아지', '고양이')
# ('강아지', '고양이') <class 'tuple'>
# 강아지
# 고양이
multy1('강아지', '고양이', 10, 20, -3.14)
# ('강아지', '고양이', 10, 20, -3.14) <class 'tuple'>
# 강아지
# 고양이
# 10
# 20
# -3.14


# 일반 매개변수 + 가변 매개변수가 있는 함수 정의
# 함수안에 매개변수 순서 주의
# def 함수명(일반 매개변수 , 초기값이 있는 매개변수, 가변 매개변수)
def multy2(number, msg='파이썬', *args) :
    return print(f'number = {number} , msg = {msg} , arg = {args} ')

multy2(1, 'Hello world!!!') 
# number = 1 , msg = Hello world!!! , arg = ()
print('-'*10)     
multy2(1, 'Hello world!!!', 1, 2, 3) 
# number = 1 , msg = Hello world!!! , arg = (1, 2, 3)
print('-'*10)     
multy2(1) 
# number = 1 , msg = 파이썬 , arg = ()
print('-'*10)     

'''
Quiz

첫번째 인자의 값이 'min'이면 다음 인자의 숫자 중 최대값을 출력하고
첫번째 인자의 값이 'max'이면 다음 인자의 숫자 중 최소값을 출력하여라
이 때 전달하는 숫자의 갯수는 가변으로 한다.

'''
#1) 함수 정의
def min_max_number( choice, *args):
    #2) choice 매개변수를 이용한 조건문
    if len(args) == 0:
        print('오류발생')        
    elif choice == 'min':
        print(f'최소값은? {min(args)}')   
    elif choice == 'max' :
        print(f'최대값은? {max(args)}')   
        
    else :
        print('오류발생')
#3) 함수 호출 테스트
min_max_number('min')  
#오류발생
min_max_number('min', 10, 20, -90, 1)
#최소값은? -90
min_max_number('max', 10, 20, -90, 1, 100)
#최대값은? 100
min_max_number('plus', 10, 20, -90, 1, 100)
#오류발생

 

3. 람다함수

람다함수
- 익명함수, 이름이 없는 함수
- filter(), map() 함수의 매개변수로 사용
# 문법1
lambda 매개변수1, 매개변수2 : 반환값
# 문법2 : 변수에 람다함수 전달, 변수는 함수 호출시 재사용 
변수명 =  lambda 매개변수1, 매개변수2 : 반환값 


# 두수의 곱을 출력하는 함수 정의
# 매개변수 O, 반환값 O
def plus_string( x, y) :
    return f' {x} 곱하기 {y}은/는 {x*y} '

print(plus_string( 8, 7))
# 8 곱하기 7는 56

# 람다 함수로 정의
plus_string2 = lambda x,y : f' {x} 곱하기 {y}은/는 {x*y} '
# 람다 함수 호출은?
print(plus_string2(8,7))
#  8 곱하기 7은/는 56

Quiz
첫 글자를 제외한 나머지 글자를 '*'로 표시하는 람다 함수를 정의하여라.

f1('홍길동')
f1('python')
f1('빅데이터인공지능')
f1('백합과장미')

방법)
첫 글자를 제외한 나머지 글자를 '*'로 표시하는 람다 함수를 정의하여라.
함수, 문자열 인덱싱, 슬라이싱 - 문자열변수[0], 문자열변수[1:]

풀이)
# 일반함수 정의
def star_string1(txt):
    return print(txt[0] + '*'*len(txt[1:]))

star_string1('홍마리아')
star_string1('김풍')

결과)

홍***
김*

# 람다함수로 정의

star_string2 = lambda txt:print(txt[0] + '*'*len(txt[1:]))

star_string2('홍마리아')
star_string2('김풍')

결과)

홍***
김*

4. filter()


# filter()
# filter(함수명|람다함수 , 리스트|튜플)
# 확인시 list(), tuple()를 이용해서 데이터형변환하거나 for 문 필요
# 리스트에서 짝수만 추출해서 새로운 리스트로 반환한다.

예제)

num_list = [ 10, 8, 5, -7, -100]

# 일반함수 사용
# 1) 함수 정의 - 매개변수는 리스트
def make_list(num_list):
    # 2)결과 리스트 정의
    result_list = [] 
    # 3) 반복문 : 매개변수의 리스트 순회
    for item in num_list :
        #4) 데이터가 짝수라면 결과 리스트에 추가
        if item % 2 == 0:
            result_list.append(item)
    # 5) 결과 리스트 반환
    return result_list
#6) 함수 호출
print(make_list(num_list))    

결과)
[10, 8, -100]


# filter(함수명 , 리스트|튜플) 사용 // 일반함수에서 if 부분 함수로 만든다.
# 짝수면 True 반환하는 함수 정의
def even_num( item ) :
    return item % 2 == 0
print(even_num(4)) # True
print(even_num(5)) # False
# filter 함수 적용
num_list = [ 10, 8, 5, -7, -100]
print(filter(even_num , num_list)) # <filter object at 0x000001CB81C70460>
print(list(filter(even_num , num_list))) # [10, 8, -100]
print(list(filter(even_num , [ 44, 7, 888]))) # [44, 888]

# filter(lambda 매개변수:반환값, 리스트|튜플) 사용
print('='*20)
num_list = [ 10, 8, 5, -7, -100]
print(list(filter( lambda item:item%2 ==0 , num_list ))) #[10, 8, -100]
print(list(filter( lambda item:item%2 ==0 , [ 44, 7, 888] ))) #[44, 888]

# for 문 + filter()
num_list = [ 10, 8, 5, -7, -100]
for item in filter( lambda item:item%2 ==0 , num_list ) :
    print(item)
# 세로로 출력된다.    
# 10
# 8
# -100

# 리스트에서 양수만 출력
numlist = [10, -30, 20, 5, -100]

# filter(함수명, 리스트|튜플) 사용
# 1) 양수면 True 반환하는 함수 정의
def positive(item):
    return item > 0
#2) filter 함수에 적용
print(list(filter(positive , numlist)))
# [10, 20, 5] 

# filter(lambda 매개변수:반환값, 리스트|튜플) 사용
print(list(filter(lambda item:item>0 , numlist)))  #[10, 20, 5]

5. map()

# map(함수명, 리스트|튜플|문자열)
# map(lambda 매개변수:반환값 , 리스트|튜플|문자열)

# 리스트의 제곱을 구해서 새로운 리스트로 만들기
numlist = [10, -30, 20, 5, -100]

# 일반 함수 이용
def double_make(numlist) :
    result_list = []
    for item in numlist :
        result_list.append(item**2)
    return result_list
print(double_make(numlist)) # [100, 900, 400, 25, 10000]
print(double_make([1, 5, 6])) # [1, 25, 36]

   
# map(함수명, 리스트|튜플|문자열) 함수 이용
# 매개변수를 제곱으로 만들어 반환하는 함수 정의
def double_number(item) :
    return item**2
# map () 적용
print(map((double_number), numlist)) # <map object at 0x000001FCFCEEB190>
print(list(map((double_number), numlist))) # [100, 900, 400, 25, 10000]

# map(lambda 매개변수:반환값 , 리스트|튜플|문자열) 적용
print(list(map( lambda item:item**2 , numlist))) # [100, 900, 400, 25, 10000]
print(double_make([1, 5, 6])) # [1, 25, 36]

 

# 두 리스트에서 인덱스가 같은 값을 서로 곱한 후 리스트로 만들기
list1 = [2,3,7]
list2 = [4,5,9]
# map(함수명, 리스트|튜플|문자열) 함수 이용
def multy_number(x, y):
    return x*y
print(list(map(multy_number, list1, list2)))
# map(lambda 매개변수:반환값 , 리스트|튜플|문자열) 적용
print(list(map(lambda x,y : x*y, list1, list2))) # [8, 15, 63]


'''
Quiz.

4개의 리스트 각 아이템 요소가 '-'로 연결되어 출력되도록 하여라
최종 결과는 리스트로 저장되어야 하며 map() 함수를 활용한다

num_list = [100, 200, 300, 400]
name_list = ['길동', '동미', '미영', '영철']
gender_list = ['남','여','여','남']
address_list = ['서울','대전','부산','대구']


'''
num_list = [100, 200, 300, 400]
name_list = ['길동', '동미', '미영', '영철']
gender_list = ['남','여','여','남']
address_list = ['서울','대전','부산','대구']

def data_join( num, name, gender, address):
    return f'{num}-{name}-{gender}-{address}'
print(data_join('100', '길동', '남', '서울')) #100-길동-남-서울
print(list(map(data_join, num_list, name_list, gender_list, address_list)))
# ['100-길동-남-서울', '200-동미-여-대전', '300-미영-여-부산', '400-영철-남-대구']
print(list(map(lambda num, name, gender, address:f'{num}-{name}-{gender}-{address}',num_list, name_list, gender_list, address_list)))
# ['100-길동-남-서울', '200-동미-여-대전', '300-미영-여-부산', '400-영철-남-대구']