[Python]

파이썬 - lambda 함수

AI gina 2022. 5. 21. 09:30
  • Lambda 함수
    • 단일문으로 표현되는 익명함수이다.
    • 익명함수란 이름이 없는 구현체만 존재하는 간단한 함수를 의미한다.
    • 코드 상에서 한번만 사용되는 기능이 있을 때, 굳이 함수로 만들지 않고 1회성으로 만들어서 쓸 때 사용한다.
    • lambda 예약어로 만든 함수는 return 명령어가 없어도 결괏값을 돌려준다.
def counter():
    i = 0
    def count():
        nonlocal i 
        i +=1
        return i
    return count
    
c = counter()
for i in range(10):
    print(c(),end=' ')
# 일반 함수
def add(a,b):
    return a+b
print(add(2,3))


# lambda 함수 
# lambda 인자: 표현식
(lambda a,b : a+b)(2,4)

 

filter, map, reduce

  • lambda가 유용하게 사용되는 3가지 대표적 함수이다.
  • 함수형 프로그래밍의 기본 요소이기도 하다.
  • filter : 특정 조건을 만족하는 요소만 남기고 필터링한다.
    filter(function, iterable)
  • map : 각 원소를 주어진 수식에 따라 변형하여 새로운 리스트를 반환한다.
    map(function, iterable)   *이터러블: 반복 가능한 객체(리스트,튜블 등)
  • reduce : 차례대로 앞 2개의 원소를 가지고 연산. 연산의 결과가 또 다음 연산의 입력으로 진행된다. 따라서 마지막까지 진행되면 최종 출력은 한개의 값만 남게 된다.
 
list_a = [23,245,55,77,44,94]

#리스트에서 짝수인 값들만 새로운 리스트에 담아서 리턴하세요.

def even(n) :
    return n %2 ==0

even(3)

result_list=[]
for value in list_a :
    if even(value) :
        result_list.append(value)
        
print(result_list)

[44, 94] #결과값
list(filter(even, list_a)) # filter(조건 함수, 순회 가능한 데이터)

[44, 94] #결과값
list(filter(lambda n:n%2==0,list_a)) #filter(lambda 인자 : 표현식, iterable)

[44, 94] #결과값

 

def f(x):
    return x > 5 and x < 10
a = [8, 3, 2, 10, 15, 7, 1, 9, 0, 11]
list(filter(f, a))


#함수 f를 람다표현식으로 바꾸기
print(list(filter(lambda x : x>5 and x<10, a)))

[8, 7, 9] #결과값

 

# map(function, iterable)
# 주어진 리스트, 리스트의 제곱을한 숫자로 새로운 리스트
nums = [1, 2, 3, 6, 8, 9, 10, 11, 13, 15]
def f(n):
    return n**2

#람다 표현식을 인수로 사용하기  ex) map 
list(map(lambda n : n**2, nums)) 

[1, 4, 9, 36, 64, 81, 100, 121, 169, 225]  #결과값

 

# 람다 표현식에 조건부 표현식 사용하기
# lambda 매개변수들: 식1 if 조건식 else 식2

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

result_list = list(map(lambda x : str(x) if x %3 ==0 else x, a))
print(result_list)

def mul(x) :
    if x%3 ==0 :
        return str(x)
    else :
        return x
mul(3)

[1, 2, '3', 4, 5, '6', 7, 8, '9', 10] #결과값
'3'
# lambda 매개변수들: 식1 if 조건식1 else 식2 if 조건식2 else 식3
# 이렇게 가독성이 떨어질 때에는 그냥 def 함수로 만들고 if elif else 사용권장
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

list(map(lambda x : str(x) if x ==1 else float(x) if x==2 else x+10, a))

['1', 2.0, 13, 14, 15, 16, 17, 18, 19, 20] #결과값

 

# map에 객체를 여러 개 넣기
# map은 리스트 등의 반복 가능한 객체를 여러 개 넣을 수도 있습니다. 
# 다음은 두 리스트의 요소를 곱해서 새 리스트를 만듭니다.

a = [1, 2, 3, 4, 5]
b = [2, 4, 6, 8, 10]
list(map(lambda x, y: x * y, a, b))

[2, 8, 18, 32, 50] #결과값

reduce 사용하기

  • from functools import reduce    *기본함수 아님 주의.
  • reduce(함수, 반복가능한객체)

-> 반복되는 객체에서 인자를 두개씩 사용해서 결과값을 만들고,

    결과값과 다음 인자로 또 함수를 실행하는 것을 반복한다.

 

# reduce 사용하기
#  from functools import reduce
#  reduce(함수, 반복가능한객체)

from functools import reduce   #functools에 있는 reduce를 임포트 하겠다.
a = [1,2,3,4,5]
reduce(lambda x,y : x+y, a)   
15   #결과값


#1. x=1, y=2, 결과값:3
#2. 1번에서 수행한 결과값 x=3, y=3(다음요소), 결과값:6
#3. 2번에서 수행한 결과값 x=6, y=4(다음요소), 결과값:10
#4. 10+5=15
# 최종결과값 15
n = [5,4,3,2,1]
f = reduce(lambda x,y:x*y, n)
print(f)
120 #결과값

 

# List Comprehesions (리스트 표현식 : 식으로 지정해서 생성된 것을 리스트로 잡아두는 것)
# 리스트 내부에 코드를 작성
# for문에서 반복되는 변수를 콜론(:)다음에 줄을 바꿔 들여쓰기하는것이 아니라, for문앞에 작성
# 컴프리헨션은 if 키워드를 지원. 이때 if키워드는 for문 다음에 위치해야 함.
# for 키워드와 if키워드를 몇번이고 반복할 수 있음.

a = [3,33,22,44,25,66,4,3,6]
[i for i in a if i > 20 and i <40 ]

[33, 22, 25]  #결과값

 

함수 연습문제

  1. 주어진 숫자 리스트의 평균을 구하는 함수를 출력하시오
  2. 해당 숫자가 소수인지 아닌지 판별하시오.
  3. 2부터 해당 숫자사이에 소수가 몇개인지 출력하는 함수를 구하시오
# 1. 주어진 숫자 리스트의 평균을 구하는 함수를 출력하시오

# 일반 함수
def avg(a) :                   #함수 선언
    sum(num)/len(num)          #수행식
avg(a)                         #함수 실행


# lambda 함수
(lambda a : sum(num)/len(num))(a)    #lambda함수 정의와 동시에 사용하려면 () 붙임

24.25    #결과값
# 2. 해당 숫자가 소수인지 아닌지 판별하시오.

x=int(input("숫자입력: "))

def prime_count(x) :
    a = range(2,x)
    count=0
    for i in a :
        if x % i ==0:
            count+=1
            return False
        else :
            return True


prime_count(x)

숫자입력: 19 #입력값
True         #출력값
# 3. 2부터 해당 숫자사이에 소수가 몇개인지 출력하는 함수를 구하시오
# 블로그 참고함


def prime_count(x):
    a = set([i for i in range(3, x+1, 2)]) #x미만 자연수 중 홀수 i의 집합 a (소수는 짝수가 될 수 없음)
    for i in range(3, x+1, 2) :
        if i in a:
            a -= set([i for i in range(i*2, x+1, i)]) #(i를 제외한) i 배수들의 집합을 a에서 뺀 값을 a에 재할당 
                                                      #(에라토스테네스의 체 이용하여 배수들 걸러낸 나머지 소수들을 a에 담음)
    return len(a)+1  #a 집합 원소개수+1 (짝수는 안되지만 2는 소수이므로 1개 더해줌)


prime_count(9)  #숫자 9를 인자로 함수 실행

4   #결과값

 

클로저

  • 변수의 사용범위 지역변수, 전역변수, global 확인
  • https://dojang.io/mod/page/view.php?id=2364 참고
  • 클로저(closure)란, 외부 함수에 접근할 수 있는 내부 함수
  • 혹은 이러한 원리를 일컫는 용어인데 스코프에 따라서 내부함수의 범위에서는 외부 함수 범위에 있는 변수에 접근이 가능하지만 그 반대는 실현이 불가능하다는 개념이다.
  • 특징으로는 외부함수는 외부함수의 지역변수를 사용하는 내부함수가 소멸될 때까지 소멸되지 않는다.예를 들어 한 함수안에 다른 함수가 있다면 그 안의 함수는 바깥에 정의해놓은 변수를 사용할 수 있지만 그 반대는 가능하지 않다. (외부속성을 내부속성처럼 사용하고 싶을 때 사용) 
#전역변수, 지역변수 이해

#name = 'kim'        #전역변수 (범위가 넓어서 함수 내부에서도 사용 가능.)
def foo() :
#     global name
    name = 'kang'     #지역변수
    print(locals())


    #     return name
# print(globals())
foo()
print(name)         #외부에서는 전역변수만 사용 가능함.
{'name': 'kang'}
kang

 

 

# 함수의 중첩

def hello():   #2
    message = "hello python"  #3
    def say_hello():     #5
        print(message)   #6 
    say_hello()    #4
    
hello()   #1
hello python

 

 

#내부에서 사용된 변수는 외부에서 사용할 수 없다.

def a() :
    x =10    #global (함수 중첩시 밖의 함수의 변수가 전역변수 역할함)
    def b() :
        x=20  #local (함수 중첩시 내부 함수의 변수가 지역변수 역할함)
    b()
    print(x)
    
a()
10

 

x = 10          # 전역 변수
def foo():
    global x    # 전역 변수 x를 사용하겠다고 설정
    x = 20      # x는 전역 변수 (****전역변수 x=10을 사용하나, 전역변수를 x=20으로 바꿈. )
    print(x)    # 전역 변수 출력
 
foo()
print(x)        # 전역 변수 출력
20
20

 

def A():
    x = 10
    y = 100
    def B():
        x=20
        def C():
            nonlocal x
            nonlocal y
            x = x+30
            y = y+300
            print(x)
            print(y)
        C()
    B()
A()
50
400

 

 

x = 1
y = 10
def A():
    x = 10
    y = 100
    def B():
        x = 20
#        y = 200
        def C():
            global x
            nonlocal y
            y = y + 100
            x = x + 30
            print(x,y)
        C()
    B()
A()
31 200

 

#일급 객체
def my_func():
    name = 'kang'
    def hello():
        print('hi!!!!!', name)
    return hello  #함수가 객체로 리턴됨. 파이썬은 함수를 일급객체로 취급할 수 있음.
    
my_func()()    #함수 뒤어 () 있어야 실행 됨.


return_value = my_func()
return_value
hi!!!!! kang
 
<function __main__.my_func.<locals>.hello()>

 

 

연습문제

호출횟수를 세는 함수 만들기. c를 호출 할 때마다 호출 횟수가 출력되도록 작성

def counter():
    i = 0
    def count():

        ...


c = counter()
for i in range(10):
    print(c(), end=' ')
1 2 3 4 5 6 7 8 9 10