Python
람다
haventmetyou
2023. 10. 17. 15:02
람다 표현식으로 함수 만들기
>>> # 함수식
>>> def plus_ten(x):
... return x + 10
...
>>> plus_ten(1)
11
>>>
>>> # 람다 표현식
>>> lambda x: x + 10
<function <lambda> at 0x000001A61B9FCD60>
>>> # 이 상태로는 함수 호출 x, 이름이 없는 함수를 만들기 때문에 익명 함수라고 부름
>>> print( lambda x: x + 10 )
<function <lambda> at 0x000001A61B9FCE00>
>>>
>>> list( lambda x: x + 10 )
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'function' object is not iterable
>>>
>>> plus_ten = lambda x: x + 10 # 람다로 만든 익명 함수 호출하려면 변수에 할당
>>> print( plus_ten(1) )
11
>>>
람다 표현식 자체 호출
>>> (lambda x: x + 10)(1)
11
>>> (lambda x: x + 10)(2)
12
람다 표현식 안에서는 변수를 만들 수 없음
>>> (lambda x: y = 10; x + y)(1)
File "<stdin>", line 1
(lambda x: y = 10; x + y)(1)
^
SyntaxError: invalid syntax
람다 표현식 바깥에 있는 변수는 사용할 수 있음
>>> y = 10
>>> (lambda x: x + y)(1)
11
>>> (lambda x, y: x + y)(1, 2)
3
람다 안에서 값을 할당하지 않고 매개변수 2개로 만들면 적용 가능
람다 표현식 사용 이유: 함수의 인수 사용 가능, 간단하게 함수를 만들기 위해 > 대표적인 예시: map
람다 표현식 인수로 사용
>>> # 함수식
>>> def plus_ten(x):
... return x + 10 # x값에 10을 더해서 반환
...
>>> list( map(plus_ten, [1, 2, 3]) )
[11, 12, 13]
>>>
>>>
>>> # 람다식(람다 표현식)
>>> list( map(lambda x: x + 10, [1, 2, 3]) )
[11, 12, 13]
>>>
>>>
>>> # list로 묶지 않으면 객체 자체 출력
>>> (map(lambda x: x + 10, [1, 2, 3]))
<map object at 0x000001A61B5DBCA0>
람다 표현식으로 매개변수 없는 함수 만들기
>>> # lambda 뒤에 아무것도 지정하지 않고 :(콜론) 붙이기
>>> # 콜론 뒤에는 반드시 반환할 값이 있어야 함, 표현식은 반드시 값으로 평가되어야 한다
>>>
>>> (lambda : 1)()
1
>>> x = 10
>>> (lambda : x)()
10
>>> (lambda : x)(10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: <lambda>() takes 0 positional arguments but 1 was given
>>>
>>>
>>> # 매개 변수가 없는 함수식
>>>
>>> def hello():
... return 10
...
>>> x = hello()
>>> print(x)
10
람다 표현식과 map, filter, reduce 함수 활용
람다 표현식에 조건부 표현식 사용
lambda 매개변수들: 식1 if 조건식 else 식2
>>> # 람다 표현식 안에서 if 사용
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list( map(lambda x: str(x) if x % 3 == 0 else x, a) )
[1, 2, '3', 4, 5, '6', 7, 8, '9', 10]
>>>
>>> # for 반복문 안에서 if 사용
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list_a = []
>>>
>>> for i in a:
... if (i % 3) == 0:
... list_a.append( str(i) )
... else:
... list_a.append( i )
...
>>>
>>> list_a
[1, 2, '3', 4, 5, '6', 7, 8, '9', 10]
요소가 3의 배수일 때 str(x)로 요소를 문자열로 만들어 반환, 아닐 때는 그대로 반환
람다 표현식에서 if를 사용했다면 반드시 else를 사용해야 함, 안 쓰면 문법 에러, elif 사용 불가능
조건부 표현식은 식1 if 조건식1 else 식2 if 조건식2 else 식3 형식으로 if를 연속으로 사용해야 함
lambda 매개변수들: 식1 if 조건식1 else 식2 if 조건식2 else 식 3
>>> # 람다 표현식에서 조건부 표현식 사용
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> # 리스트에서 1은 문자열로 변환, 2는 실수로 변환, 3 이상은 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]
>>>
>>>
>>> # 람다 아닌 다른 방법 1
>>> # for 반복문으로 같은 식 만들기
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> list_a = []
>>>
>>> for i in a:
... if i == 1:
... list_a.append( str(i) )
... elif i == 2:
... list_a.append( float(i) )
... else:
... list_a.append( i + 10 )
...
>>> print(list_a)
['1', 2.0, 13, 14, 15, 16, 17, 18, 19, 20]
>>>
>>> # 람다 아닌 다른 방법 2
>>> # def로 함수 만들기
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> def f(x):
>>> if x == 1:
>>> return str(x)
>>> elif x == 2:
>>> return float(x)
>>> else:
>>> return x + 10
>>>
>>> print( list(map(f, a)) )
>>> print( tuple(map(f, a)) )
>>>
>>> # 실행 결과
['1', 2.0, 13, 14, 15, 16, 17, 18, 19, 20]
('1', 2.0, 13, 14, 15, 16, 17, 18, 19, 20)
이런 경우는 억지로 람다 표현식 사용하지 않고 def로 함수 만들어 if, elif, else를 사용하는 것 권장
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]
>>>
>>> # 요소의 값이 다른 경우
>>> a = [1, 2, 3, 4, 5]
>>> b = [2, 4, 6, 8]
>>> list( map(lambda x, y: x * y, a, b) )
[2, 8, 18, 32]
filter 사용
>>> # filter(함수, 반복가능한객체)
>>>
>>> # def 함수 만들어 filter 사용
>>> def f(x):
... return x > 5 and x < 10
...
>>> a = [8, 3, 2, 10, 15, 7, 1, 9, 0, 11]
>>> list( filter(f, a) )
[8, 7, 9]
>>>
>>> # 람다 표현식
>>> a = [8, 3, 2, 10, 15, 7, 1, 9, 0, 11]
>>> list( filter( lambda x: x > 3 and x < 10, a) )
[8, 7, 9]
filter는 반복 가능한 객체에서 특정 조건에 맞는 요소만 가져오는데, 지정한 함수의 반환값이 True일 때만 해당 요소 가져옴
reduce 사용
>>> # from functools import reduce
>>> # reduce(함수, 반복가능한객체)
>>>
>>> # def 함수
>>> def f(x, y): # 매개 변수 x, y
... return x + y
...
>>> a = [1, 2, 3, 4, 5]
>>> from functools import reduce
>>> reduce(f, a)
15
>>>
>>> # 람다
>>> a = [1, 2, 3, 4, 5]
>>> from functools import reduce
>>> reduce( lambda x, y: x + y, a )
15
map, filter, reduce 리스트 표현식
>>> # 리스트 표현식 - filter 람다 대신
>>> a = [8, 3, 2, 10, 15, 7, 1, 9, 0, 11]
>>> [ i for i in a if i > 5 and i < 10 ]
[8, 7, 9]
>>>
>>> # 람다
>>> a = [8, 3, 2, 10, 15, 7, 1, 9, 0, 11]
>>> list( filter( lambda x: x > 3 and x < 10, a) )
[8, 7, 9]
>>>
>>> # for, while 반복문 처리 - reduce 람다 대신
>>> a = [1, 2, 3, 4, 5]
>>> x = a[0]
>>> for i in range( len(a) - 1 ):
... x = x + a[i + 1]
...
>>> x
15
>>> # 람다
>>> from functools import reduce
>>> reduce( lambda x, y: x + y, a )
15
연습 문제 예제
# 32.4번 연습 문제: 이미지 파일만 가져오기
# 다음 소스 코드를 완성하여 확장자가 .jpg, .png인 이미지 파일만 출력되게 만드세요
# 람다 표현식을 사용해야 하며 출력 결과는 리스트 형태라야 합니다
# 람다 표현식에서 확장자를 검사할 때는 문자열 메서드를 활용하세요
files = ['font', '1.png', '10.jpg', '11.gif', '2.jpg', '3.png', 'table.xslx', 'spec.docx']
print(list(filter(lambda x: x.find('.jpg') != -1 or x.find('.png') != -1, files)))
# 32.5번 심사 문제: 파일 이름 한꺼번에 바꾸기
# 표준 입력으로 숫자.확장자 형식으로 된 파일 이름 여러 개가 입력됩니다
# 다음 소스 코드를 완성해 파일 이름이 숫자 3개이면서 앞에 0이 들어가는 형식으로 출력되게 만드세요.
# ex) 1.png > 001.png, 99.docx > 099.docx
# 람다 표현식을 사용해야 하며 출력 결과는 리스트 형태라야 합니다
# 람다 표현식에서 파일명을 처리할 때는 문자열 포매팅과 문자열 메서드를 활용하세요
files = input().split()
print(list( map(lambda x: '{0:03d}'.format(int(x.split('.')[0])) + '.' + x.split('.')[1], files )))
list( map(lambda x: '{0:03d}'.format(int(x.split('.')[0])) + '.' + x.split('.')[1], files ))
map(lambda x: '{0:03d}'.format(int(x.split('.')[0])) + '.' + x.split('.')[1], files )
# 실행 결과
1.jpg 10.png 11.png 2.jpg 3.png # 입력 값
['001.jpg', '010.png', '011.png', '002.jpg', '003.png']