-
람다 표현식으로 함수 만들기
>>> # 함수식 >>> 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']