IT_Python

[파이썬기초] Lambda 함수. filter/map/reduce. 필터링/변환, 치환/연속 연산

soyounism 2021. 12. 17. 10:15
  • Lambda 함수
    • 원래 함수에 이름을 줬는데, 이름 없이도 사용가능
    • 단일문으로 표현되는 익명함수
    • 익명함수란 이름이 없는 구현체만 존재하는 간단한 함수를 의미
    • 코드 상에서 한번만 사용되는 기능이 있을 때, 굳이 함수로 만들지 않고 1회성으로 만들어서 쓸 때 사용.

 

(람다함수)

sq=lambda a:a**2   #a파라미터(return없이) 입력:출력
type(sq)

결과

function

 

(기존함수)

def square2(x):
    return x**2

square2(5)

결과

25

 

#일반 x+y함수 만들기
def add1(x, y):
    return x + y

print(add1(10,20))

print('--------')

#람다로
add2 = lambda x,y:x+y #파라미터 2개니까 x,y 2개하고 :
print(add2(10, 20))

결과

30

------

30

 

#람다. 어디에 많이 사용하나?


strings = ['bob', 'charles', 'alexander3', 'teddy']

#문자열 길이 반환하는 함수
def gilee(s):
    return len(s)  

print(gilee('goods'))

print('-------')

#문자열 길이로 정렬해보자
strings.sort(key=gilee)  

#sort의 key 파라미터로 제어가능. key 파라미터는 함수!!
#그런데 이때 만든 gilee 함수는 여기에만 쓰잖아. 공간낭비야.
#이때 람다로!!


print(strings)

 

#람다로 공간줄이자!

strings.sort(key=lambda s:len(s))
print(strings)

결과

['bob', 'teddy', 'charles', 'alexander3']
 
 
 

filter, map, reduce

  • lambda가 유용하게 사용되는 3가지 대표적 함수
  • 함수형 프로그래밍의 기본 요소이기도 함
  • filter : 특정 조건을 만족하는 요소만 남기고 필터링
  • map : 각 원소를 주어진 수식에 따라 변형하여 새로운 리스트를 반환
  • reduce : 차례대로 앞 2개의 원소를 가지고 연산. 연산의 결과가 또 다음 연산의 입력으로 진행됨. 따라서 마지막까지 진행되면 최종 출력은 한개의 값만 남게 됨
 
filter(함수, 리스트)
리스트에서 필터링하는 것
함수가 각 리스트 함수에 각 파라미터로 불려서, 
그 함수가 참이되면 살아남고, 아니면 아웃
 
nums = [1, 2, 3, 6, 8, 9, 10, 11, 13, 15]
#짝수만 필터링하고싶다

def ham(n):
    return n % 2 == 0 #짝수인 경우만 return 되는 함수

print(ham(3))


#filter함수에 넣어서 필터링(T,F). filter(함수, 리스트)
list(filter(ham,nums))

#filter 함수 내부에서 nums를 차례대로 순회 
#각 원소에 ham함수를 적용시켜보고
#true를 반환시키면 filter함수에 적용시키고 false면 버림

 

#ham 함수역시 여기말고 다른데서는 안쓰이니까. 공간낭비

list(filter(lambda n:n%2==0, nums))

결과동일

 

 

  • map : 각 원소를 주어진 수식에 따라 변형하여 새로운 리스트를 반환
매핑시켜서 다른 리스트를 만드는 것
map(함수,리스트)
 
 
#map
# 주어진 리스트, 리스트의 제곱한 숫자로 새로운 리스트 만들기


nums = [1, 2, 3, 6, 8, 9, 10, 11, 13, 15]

map(lambda n:n**2, nums)

list(map(lambda n:n**2, nums))

결과

[1, 4, 9, 36, 64, 81, 100, 121, 169, 225]
 
 
nums = [1, 2, 3, 6, 8, 9, 10, 11, 13, 15]

#짝수인것은

#일반 함수로
print(list(map(ham, nums))) 

#map+lambda
list(map(lambda n:n%2==0, nums))
 
  • reduce : 차례대로 앞 2개의 원소를 가지고 연산.
  • 연산의 결과가 또 다음 연산의 입력으로 진행됨.
  • 따라서 마지막까지 진행되면 최종 출력은 한개의 값만 남게 됨
 
#reduce

import functools

a = [1, 3, 5, 8]
# 리스트 내의 모든 숫자의 합

functools.reduce(lambda x,y:x+y, a)
#1+3->+5->+8

결과

17

 

[연습문제]

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

def mean(nums):
    # sum 내장 함수로 대체 가능
#     _sum = 0
#     for i in nums:
#         _sum += i
    
    return sum(nums) / len(nums)

print(mean([1, 2, 3]))
print(mean([1, 2, 3, 4, 5]))
print(mean([1, 2, 3.0, 3.9, 8.7]))

 

# 소수 판별 (1과 자기 자신으로만 나눠지는 수)
# 입력: 양의 정수 1개
# 출력: boolean (소수: True, 합성수: False)

# 17<-소수
# 2, 3, 4, 5, 6, 7, 8, .... 15,16
def is_prime(num):
    for i in range(2, num): #리스트 num-1까지 생성
        if num % i == 0: # 나눠 떨어지면 ex> 17/2, 17/3... 의 나머지가 0
            return False
    return True  #if절에 해당안되면 true
    
#is_prime함수 : 2 ~ num-1 까지 원소중에서
# i로 나눠떨어지면 false
# 아니면 true 반환

print(is_prime(100))
print(is_prime(89))
print(is_prime(17))
print(is_prime(2))

# 2, 3, 4, 5, 6, 7 -> 소수는 4개
# 2, 3, 4, 5 -> 소수는 3개

# 입력: 양의 정수 1개
# 출력: 2-해당 숫자 사이의 소수의 개수

def num_prime(num):
    count = 0 #숫자셀 변수
    for i in range(2, num+1): #2~num까지중에(num이면, range가 num-1까지잖아!
        if is_prime(i): #i가 소수인가 아닌가? 위에 함수 호출
            count += 1 #if절 T면, count+1. F인경우에는 안걸려
    return count

print(num_prime(7))
#2,3,4,5,6,7 중에 소수 2,3,5,7: 4개

print(num_prime(5))
print(num_prime(100))

 

 

*참고

#range(2 ~ num-1) 까지 숫자중에 소수인것

def t1(num):
    for i in range(2, num): 
        if num % i == 0: 
            return False
    return True  


#range (x~num)까지 중 소수의 갯수
def t2(num):
    count = 0 
    for i in range(2, num+1): 
        if t1(i): 
            count += 1 
    return count

print(t2(7))
# 2,3,5,7 4개
 
 
Q. is_prime 함수안에 for range(2, num)으로 되어있는 반복문 자체가 있는데...