본문 바로가기
python

[python]파이썬 - 함수function2 lambda

by skysline 2023. 1. 24.
반응형

람다 함수(lambda)

  • 한줄 짜리 간단한 함수를 만들때 사용
  • 1회용 함수를 만들때 많이 사용
  • 람다 함수는 아주 간단한 파라미터가 정의되거나 반환하는 함수일 경우 사용
 
 
 
def add(num1,num2):
    return num1+num2
add(1,2)
 
3
 
 
 
add_lambda = lambda num1,num2: num1+num2 # 함수도 객체다!(파이썬은 다 객체다.)
add_lambda(1,2)
 
3
 
 
 
my_max = max
my_max([100,101,34])
 
101
 
 
 
square = lambda x:x**2
square(5)
 
25
 
def get_max(lst):
    result = max(lst)
    return result
 
 
 
get_max = lambda x : max(x)
get_max([1,2,3])
 
3
 
def get_size(lst):
    result = max(lst) - min(lst)
    return result
 
 
get_size = lambda x : max(x) - min(x)
get_size([1,2,3,4,5,6])
 
5
 
def get_even(lst):
    result = []
    for n in lst:
        if n % 2 == 0:
            result.append(n)
    return result 
 
 
 
get_even = lambda x:[ i for i in x if i%2 == 0]
get_even(range(0,10))
 
[0, 2, 4, 6, 8]
 

클로져(Closure)

  • 함수안에 함수(내부함수)를 만들수 있다.
  • 함수를 둘러싼 상태(지역변수)를 기억하고 있다가, 내부함수를 실행할때 기억한 지역변수를 처리한다.
 
 
 
def outer(outer_param):
    a = 10
    pass
    def inner(): # 내부함수, a 변수와 ,outer_param 파라미터 접근 가능!
        # outer_param 대해서 처리 
        pass
 
 
 
 
def do_outer(a,b):
    def do_inner(): # 내부함수 입장에서 외부함수 지역변수와 파라미터 접근 가능!
        return a + b
    return do_inner # 내부 함수의 주소를 반환

inner_result1 = do_outer(10,20)
inner_result2 = do_outer(30,50)
print(inner_result1, inner_result2)
 
<function do_outer.<locals>.do_inner at 0x7f13bdbb9200> <function do_outer.<locals>.do_inner at 0x7f13bdbb9f80>
 
 
 
inner_result1()
 
30
 
 
 
inner_result2()
 
80
 

콜백함수(Callback Function)

  • 함수의 인자로 사용되는 함수를 말한다.
 
  • 두수를 인자로 받아 더하는 함수와 빼는 함수를 만든다고 가정
  • 두개의 함수 모두 실수가 들어올경우 정수로 변경해야하는 공통 기능이 있어야한다고 가정
  • 실수를 정수로 변경하는 공통기능은 어떠한 함수에 구현
  • 그래서 이 어떠한 함수에 인자로 더하는 함수와 빼는 함수를 넣어서 더하는 처리와 빼는 처리를 한다면.....
 
 
 
def convert_int(callback,a,b):
    # 공통기능 부분
    a = int(a)
    b = int(b)
    return callback(a,b) # 인자로 받은 콜백함수를 실행하여 결과값을 반환!!
 
 
 
def add_func(num1,num2):
    return num1+num2
def sub_func(num1,num2):
    return num1-num2

convert_int(add_func,11.5,20.222)
 
31
 
 
 
convert_int(lambda a,b:a*b, 10.11,3.0)
 
30
 
 
map_obj = map(lambda x:x**0.5 , range(2,10))
map_obj
 
<map at 0x7f13bdc3cc50>
 
 
 
list(map_obj)
 
[1.4142135623730951,
 1.7320508075688772,
 2.0,
 2.23606797749979,
 2.449489742783178,
 2.6457513110645907,
 2.8284271247461903,
 3.0]
 
 
 
map_obj = map(lambda x1,x2 : x1 + x2 , [1,2,3] , [4,5,6] )
list(map_obj)
 
[5, 7, 9]
 
 
 
list1 = [1,2,3]
list2 = [4,5,6]
list3 = [7,8,9]

map_obj = map(lambda x1,x2,x3 : x1*x2*x3 , list1,list2,list3)
list(map_obj)
 
[28, 80, 162]
 
 
def do_func(x):
    if x % 2 == 0:
        return x
    else:
        return 0
 
 
 
 
lst = [1,2,3,4,5,6,7,8,9]
map_obj = map(do_func,lst)
list(map_obj)
 
[0, 2, 0, 4, 0, 6, 0, 8, 0]
 
map 함수를 이용해서 zip 함수 구현해보자
zip 함수가 없다고 가정한다.

ex)
list1 = [100,200,300]
list2 = [400,500,600]

zip_func = map(func, list1,list2)
for x1,x2 in zip_func:
    print(x1,x2)

Output:
100 400
200 500
300 600
 
 
 
list1 = [100,200,300]
list2 = [400,500,600]

zip_func = map(lambda x1,x2 : (x1,x2) , list1,list2)
for x1,x2 in zip_func:
    print(x1,x2)
 
100 400
200 500
300 600
 
map 함수를 이용해서 enumerate 함수 구현해보자
enumerate 함수가 없다고 가정한다.

ex)
lst = [100,200,300]

enumerate_func = map(func, iterables)
for i,v in enumerate_func:
    print(i,v)

Output:
0 100
1 200
2 300
 
 
lst = [100,200,300]
# def cb_func(x1,x2):
#     return x1,x2
enumerate_func = map(lambda x1,x2 : (x1,x2), range(len(lst)) , lst)
for i,v in enumerate_func:
    print(i,v)
 
0 100
1 200
2 300
 

Decorator(장식하다,꾸미다)

  • 코드를 변경하지 않고 기능을 추가하거나 수정하고 싶을때 정의하는 표현식
  • 내부함수의 주소를 리턴하는 클로져와 비슷하고 함수를 다른함수의 인자로 전달하는 방식과 비슷하다.
  • 그냥 두가지 방식을 합쳤다고 보면 된다.
 
 
def decorator_func(org_func): # 함수를 인자로 받는다.
    def wrapper_func(): # 내부함수를 구현한다.
        print("org_func 가 실행 되기전 입니다.")
        org_func() # org_func 함수를 실행
    return wrapper_func # 내부함수의 주소를 반환

def do_func():
    print("original 함수가 실행 되었습니다.")
# result == wrapper_func
result = decorator_func(do_func) # 데코레이터 함수에 감싸고자하는 함수의 주소를 인자로 넣는다.
 
 
 
 
# wrapper_func()
result() # wrapper_func() -> 그안에 코드가 실행된다. -> 인자로 받은 함수가 실행된다.
 
org_func 가 실행 되기전 입니다.
original 함수가 실행 되었습니다.
 
 
 
def decorator_func(org_func): # 함수를 인자로 받는다.
    def wrapper_func(): # 내부함수를 구현한다.
        print("org_func 가 실행 되기전 입니다.")
        org_func() # org_func 함수를 실행
    return wrapper_func # 내부함수의 주소를 반환

# decorator_func(do_func)
@decorator_func
def do_func():
    print("original 함수가 실행 되었습니다.")
 
 
 
do_func()
 
org_func 가 실행 되기전 입니다.
original 함수가 실행 되었습니다.
 
  • 데코레이터로 감싸는 함수의 파라미터를 정의해야한다면?
 
 
 
def decorator_func(org_func):
    def wrapper_func(*args,**kwargs):
        print(f"콜백함수가 실행되기 전입니다.")
        result = org_func(*args,**kwargs)
        print(f"콜백함수가 실행 완료 되었습니다.")
        return result
    return wrapper_func

# decorator_func(do_func)
@decorator_func
def do_func(a,b): # wrapper_func(*args,**kwargs)
    return a+b

do_func(3,5)
 
콜백함수가 실행되기 전입니다.
콜백함수가 실행 완료 되었습니다.
8
 

문제 1)

행 혹은 행렬 형태의 리스트를 입력 받아 행의 크기와 열의 크기를 튜플로 반환하는 함수를 작성하시오

ex)
shape([]) -> (0,)
shape([1,2,3]) -> (3,)
shape([[1,2,3],[4,5,6]]) -> (2,3)

2차원 행렬 예시:
[
    [1,2,3],
    [4,5,6]
]
 
 
 
def shape(lst):
    if len(lst) == 0: # 리스트가 비어있을 경우
        result = 0, 
    elif type(lst[0]) is list: # 리스트안에 요소가 리스트일 경우 2차원 리스트
        result = len(lst), len(lst[0])
    else: # 1차원 리스트...
        result = len(lst),

    return result

print(shape([]))
print(shape([1,2,3]))
print(shape([[2,2,2],[3,3,3]]))
 
(0,)
(3,)
(2, 3)
 

문제 2)

행렬 형태의 리스트를 입력 받고 변경하고자하는 행의 크기와 열의 크기로 변환해서 
리스트로  반환 함수를 작성하시오
행과 열의 크기는 튜플로 받는다 . 
무조건 튜플 아니면 -1 입력이 들어온다고 가정한다.
튜플은 무조건 2개의 요소가 포함되서 들어온다고 가정한다.
튜플이 아닌 -1 이 들어올경우 1차원 형태로 flatten 시킨다.

ex)
data = [
       [1,2,3],
       [4,5,6]
]
reshape(data,-1) -> [1,2,3,4,5,6]
reshape(data,(3,2)) -> [[1,2],[3,4],[5,6]]

2차원 행렬 예시:
[
    [1,2],
    [3,4],
    [5,6]
]

reshape(data,(6,1)) -> [[1], [2], [3], [4], [5], [6]] 
2차원 행렬 예시:
[
    [1], 
    [2], 
    [3], 
    [4], 
    [5], 
    [6]
]
 
data = [
       [1,2,3],
       [4,5,6]
]
 
 
 
data = [
       [1,2,3],
       [4,5,6]
]
 
 
 
 
def reshape(lst,shape):
    flatten = [] # flatten 리스트를 담을 변수 초기화
    for item in lst: # 인자로 받은 2차원 리스트를 반복
        flatten.extend(item) # 2차원안에 있는 요소(리스트)를 확장
    result = flatten # 반환할 변수에 담음

    if shape != -1: # -1 이 아닐경우 즉, 튜플일경우
        row = shape[0] # 행갯수
        col = shape[1] # 열갯수
        result = [] # 반환할 변수 빈 리스트로 초기화
        for i in range(row): # 행 개수 만큼 반복
            start_index = i * col # start 인덱스 구하기, 0X2=0 .. 1X2=2 .. 2X2=4
            end_index = start_index + col # end 인덱스 구하기
            items = flatten[start_index:end_index] # 슬라이싱
            result.append(items) # 슬라이싱한 리스트를 추가
    return result

reshape(data,(1,6))
 
[[1, 2, 3, 4, 5, 6]]
 

문제 3)

행렬 형태의 리스트를 입력 받고 행렬을 전치하는 함수를 작성하시오
행렬 전치는 열이 행이 되고 행은 열이 된다.

ex)
data = [
       [1,2,3],
       [4,5,6]
]
transpose(data) -> [[1, 4], [2, 5], [3, 6]]

2차원 행렬 예시:
[
    [1, 4], 
    [2, 5], 
    [3, 6]
]
 
 
 
data = [
       [1,2,3],
       [4,5,6]
]

def transpose(lst):
    return [ list(tup) for tup in zip(*lst)] # zip([1,2,3],[4,5,6])

transpose(data)

[[1, 4], [2, 5], [3, 6]]
반응형

댓글