Python & Django Day8 lambda, map, filter, 데코레이터
Fastcampus Python&Django 온라인 강의를 듣고 작성한 Class note입니다.
lambda
함수만 만들고 함수가 들어갈 변수를 지정하지 않는 식.
(깔끔하다는 장점은 있으나 가독성이 떨어질 수 있어서 python3 부터는 권장하지 않는 추세이다.)
1students = []
2student1_info = {
3 "first_name": "sol",
4 "las_name" : "hyun",
5 "student_no": 3498
6
7}
8
9student2_info = {
10 "first_name": "suzy",
11 "las_name" : "bae",
12 "student_no": 1345
13
14}
15
16student3_info = {
17 "first_name": "coca",
18 "las_name" : "hyun",
19 "student_no": 4728
20
21}
22
23for i in range(1, 4):
24 students.append(eval('student%d_info'% (i)))
student_no를 기준으로 정렬해주려고 한다. 정렬해주는 함수를 한 번만 사용할 것이기 때문에 함수를 만들어서 변수에 저장하는 것은 비효율적이다. 이때 람다식을 이용하면 간결하게 해결할 수 있다.
1# lambda식 이용하기 전
2def sort_help(d):
3 return d['student_no']
4
5sorted_student = sorted(students, key = sort_help)
6
7
8# lambda식 이용해서 수정
9sorted_student = sorted(students, key = lambda x: x['student_no'])
10print(sorted_student)
lambda식 연습
1# +1 해주는 함수
2lambda x : x + 1
3
4# 3개의 값을 더해주는 함수
5lambda x, y, z : x + y + z
6
7# 2개의 값을 각각 제곱해서 더해주는 함수
8lambda x, y : x**2 + y**2
1### lambda 함수 만들기
2## 1개의 숫자를 받아서 2의 배수이면 True, 아니면 False 리턴하는 함수
3# 함수 정의
4def multiples_of_two(n):
5 if n%2 == 0:
6 return True
7 else:
8 return False
9
10# lambda식 이용
11lambda x: True if x%2 == 0 else False
12
13## 0~n개의 정수를 받아서 다 합쳐주는 함수
14def f(*x) : return sum(x)
15lambda *x : sum(x)
map
어떤 함수를 각각의 리스트에 적용 시키는 것.
1### map
2# for문 이용
3a = list(range(1, 11))
4
5result = []
6for el in a :
7 result.append(el + 1)
8
9# map 이용
10a = list(range(1, 11))
11
12result = map(lambda x : x + 1, a)
13list(result)
map 연습
1# 1) 1~100이 담긴 리스트를 fizzbuzz하기 (3의 배수이면 fizz, 5의 배수이면 buzz, 15의 배수이면 fizzbuzz)
2raw_list = list(range(1, 100+1))
3
4result = map(lambda x : 'fizzbuzz' if x%15 == 0 else
5('buzz' if x%5 == 0 else ('fizz' if x%3 == 0 else x)), raw_list)
6
7print(list(result))
filter
어떤 함수를 각각의 리스트에 적용 시키는 것은 map과 동일하고, return값이 boolean값으로 나온다.
1a = list(range(1, 10+1))
2result = []
3for el in a :
4 if el % 2 == 0:
5 result.append(el)
6
7# filter 사용
8list(filter(lambda x : x % 2 == 0, a))
filter 연습
1# 1~100까지 가진 리스트에서 50보다 큰 값만 남겨보기
2raw_list = list(range(1, 100+1))
3result = filter(lambda x : x > 50, raw_list)
4
5# 위 결과값을 받아 2의 배수만 가진 리스트 만들기
6result = filter(lambda x : x % 2 == 0, result)
7print(list(result))
reduce
1from functools import reduce
2
3a = [1, 2, 3, 4]
4
5result = reduce(lambda x, y: x + y, a)
6print(result)
- 코드 실행 과정 :
1a = [1, 2, 3, 4]에서 x, y에 1,2 받아서 더해 준다.
2a = [3, 3, 4]가 된다.
3
4다시 x, y에 3, 3을 받아서 더해준다.
5a = [6, 4] 가 된다.
6
7다시 x, y에 6, 4를 받아서 더해준다.
8result는 최종 10이 된다.
- 연습
1 ~ 10까지 가진 리스트에서 각 요소의 제곱을 더하기.
1a = list(range(1, 10+1))
2from functools import reduece
3redeuce(lambda x, y: x**2 + y**2, a)
함수를 인자로 보내는 예시 : 함수를 변수처럼 사용하기
1# 함수를 인자로 받아서 변수처럼 사용하기
2def print_start_end(func):
3 print("함수가 시작됩니다.")
4 result = func()
5 print("함수가 끝났습니다.")
6 return result
7
8def print_1_to_100():
9 for i in range(1, 100+1):
10 if i < 100:
11 print(i, end=', ')
12 else:
13 print(i)
14
15print_start_end(print_1_to_100)
16
17#----------- 결과 -------------
18함수가 시작됩니다.
191, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100
20함수가 끝났습니다.
21#-----------------------------
22
23
24# 함수를 받아서 함수 생성
25def make_print_start_end(func):
26 def new_func():
27 print("함수가 시작됩니다.")
28 result = func()
29 print("함수가 끝났습니다.")
30 return result
31 return new_func
32
33new_func = make_print_start_end(print_1_to_100)
34
35#------------------------------------------------------------
36
37def make_print_start_end(func):
38 def new_func(n):
39 print("함수가 시작됩니다.")
40 result = func(n)
41 print("함수가 끝났습니다.")
42 return result
43 return new_func
44
45def print_1_to_n(n):
46 for i in range(1, n+1):
47 if i < n:
48 print(i, end=', ')
49 else:
50 print(i)
51
52new_func = make_print_start_end(print_1_to_n)
53new_func(100)
54
55#----------- 결과 -------------
56함수가 시작됩니다.
571, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100
58함수가 끝났습니다.
59#-----------------------------
1# 인자가 여러개
2def make_print_start_end(func):
3 def new_func(*args, **kwargs): # 하나의 튜플과 딕셔너리로 packing
4 print("함수가 시작됩니다.")
5 result = func(*args, **kwargs) # unpacking
6 print("함수가 끝났습니다.")
7 return result
8 return new_func
9
10
11def print_a_to_b(a, b, c):
12 for i in range(a, b+1, c):
13 if i < b:
14 print(i, end=', ')
15 else:
16 print(i)
17
18new_func = make_print_start_end(print_a_to_b)
19new_func(1, 100, 2)
20
21
22def sum_a_to_b(a, b):
23 result = 0
24 for i in range(a, b+1):
25 result += i
26 return result
27
28new_func2 = make_print_start_end(sum_a_to_b)
29print(new_func2(1, 10))
Decorator
함수를 꾸미는 기능.
1### 함수를 꾸미자, Decorator
2def make_print_start_end(func):
3 def new_func(*args, **kwargs):
4 print("함수가 시작됩니다.")
5 result = func(*args, **kwargs)
6 print("함수가 끝났습니다.")
7 return result
8 return new_func
9
10@make_print_start_end
11def print_a_to_b(a, b, c):
12 for i in range(a, b+1, c):
13 if i < b:
14 print(i, end=', ')
15 else:
16 print(i)
17
18print_a_to_b(1, 100, 3)
함수를 만드는 함수를 호출 받아서, 넣고, 다시 결괏값으로 나온 함수를 리턴 받아서 실행시키는 구간(new_func = make_print_start_end(print_a_to_b)
new_func(1, 100, 2)
) 을 @make_print_start_end
으로 대체한다.
(참고 : https://jonnung.github.io/python/2015/08/17/python-decorator/)
-
연습
- 다음 모듈의 기능을 이용하여 함수의 실행시간을 측정하는 데코레이터 만들기
from time import time
start_time = time()
end_time = time()
executed_time = end_time - start_time
1from time import time
2start_time = time()
3end_time = time()
4
5def check_time(func):
6 def new_func(*args, **kwargs):
7 start_time = time()
8 result = func(*args, **kwargs)
9 end_time = time()
10 print("함수 실행에 걸린 시간은 ", end_time - start_time)
11 return result
12 return new_func
13
14@check_time
15def sum_1_to_n(n):
16 result = 0
17 for i in range(1, n+1):
18 result += i
19 return result
20
21result = sum_1_to_n(12345)
22print(result)
23
24#-----결과-------
25함수 실행에 걸린 시간은 0.001059055328369140676205685
26
27
28@check_time
29def gauss_sum(n):
30 return (n * (n + 1))/2
31
32gauss_sum(12345)
33#----결과------
34함수 실행에 걸린 시간은 6.9141387939453125e-06