Python
2014.04.25 15:51

Lambda 함수, 축약 함수

조회 수 13945 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print
?

단축키

Prev이전 문서

Next다음 문서

+ - Up Down Comment Print

https://wikidocs.net/64


오늘은 람다 형식과 그것을 이용하는 여러가지 함수들에 대해서 알아보겠습니다. 당장 완벽하게 소화하실 필요는 없을 것 같구요, 가벼운 마음으로 이런 것이 있다는 정도만 아셔도 되지 않을까 합니다. 람다 형식은 인공지능 분야나 AutoCAD라는 설계 프로그램에서 쓰이는 Lisp 언어에서 물려받았다고 하는데요, 함수를 딱 한 줄만으로 만들게 해주는 훌륭한 녀석입니다. 사용할 때는 아래와 같이 써주면 되지요.

lambda 인자 : 표현식

다음은 두 수를 더하는 함수입니다.

>>> def hap(x, y):
...   return x + y
...
>>> hap(10, 20)
30

이것을 람다 형식으로는 어떻게 표현할까요?

>>> (lambda x,y: x + y)(10, 20)
30

너무나 간단하죠? 함수가 이름조차도 없습니다. '그냥 10 + 20이라고 하면 돼지'라고 말씀하시면 미워잉~.

몇 가지 함수를 더 배워보면서 람다가 어떻게 이용되는지 알아보도록 하죠.

먼저 map 함수를 볼까요?

map(함수, 리스트)

이 함수는 함수와 리스트를 인자로 받습니다. 그렇죠? 그리고, 리스트로부터 원소를 하나씩 꺼내서 함수를 적용시킨 다음, 그 결과를 새로운 리스트에 담아준답니다. 말이 좀 복잡하죠? 그럴 때 예제를 보는 게 최고죠.

>>> map(lambda x: x ** 2, range(5))             # 파이썬 2
[0, 1, 4, 9, 16]  
>>> list(map(lambda x: x ** 2, range(5)))     # 파이썬 2 및 파이썬 3
[0, 1, 4, 9, 16]

위의 map 함수가 인자로 받은 함수는 lambda x: x ** 2구요, 리스트로는 range(5)를 받았습니다. range 함수는 알고계시죠? range(5) 라고 써주면 [0, 1, 2, 3, 4]라는 리스트를 돌려줍니다. 그리고 x ** 2 라는 것은 x 값을 제곱하라는 연산자죠.

map 함수는 리스트에서 원소를 하나씩 꺼내서 함수를 적용시킨 결과를 새로운 리스트에 담아주니까, 위의 예제는 0을 제곱하고, 1을 제곱하고, 2, 3, 4를 제곱한 것을 새로운 리스트에 넣어주는 것입니다.

위의 예제를 람다가 아닌 보통의 함수로 구현하면 어떻게 될까요?

이번엔 reduce 함수를 살펴봅시다.

reduce(함수, 순서형 자료)

형식은 위와 같구요, 순서형 자료(문자열, 리스트, 튜플)의 원소들을 누적적으로(?) 함수에 적용시킨답니다. 말이 진짜 어렵군요. 예제를 살펴보도록 하겠습니다.

>>> from functools import reduce   # 파이썬 3에서는 써주셔야 해요  
>>> reduce(lambda x, y: x + y, [0, 1, 2, 3, 4])
10

위의 예제는 먼저 0과 1을 더하고, 그 결과에 2를 더하고, 거기다가 3을 더하고, 또 4를 더한 값을 돌려줍니다. 한 마디로 전부 다 더하라는 겁니다. 생각보다 쉽죠?

하… 하… 하…

의기양양하게 '예'라고 대답하신 분들을 위해 짜증나는 예제를 권해드리죠~.

>>> reduce(lambda x, y: y + x, 'abcde')
'edcba'

전 원래 뭐 하나를 배우면 꼭 엽기적인 실험을 해본답니다. 더 짜증나라고 설명 안 해드릴랍니다~

그 다음은 filter를 살펴볼 차례입니다. 필터가 뭐죠? 정수기에서 물을 걸러주는 것이 필터죠? 에어컨의 바람 들어가는 곳에도 필터가 달려있구요.

filter(함수, 리스트)

파이썬의 필터는 이렇게 생겼는데요, 리스트에 들어있는 원소들을 함수에 적용시켜서 결과가 참인 값들로 새로운 리스트를 만들어줍니다. 다음은 0부터 9까지의 리스트 중에서 5보다 작은 것만 돌려주는 예제입니다.

>>> filter(lambda x: x < 5, range(10))       # 파이썬 2
[0, 1, 2, 3, 4]  
>>> list(filter(lambda x: x < 5, range(10))) # 파이썬 2 및 파이썬 3
[0, 1, 2, 3, 4]

lambda x: x<5 라고 쓰니까 왠지 수학책에서 본 듯한 느낌이 들지 않습니까? 수학자들이 파이썬을 좋아한다던데…

위의 예제가 어떻게 돌아가는지는 척 보면 아시겠죠?

0부터 9까지의 리스트에서 숫자를 하나씩 꺼냅니다.

그 숫자를 x라 하고, x < 5 가 '참'이면 살려줍니다.

살아남은 것들은 새로운 리스트에 넣어줍니다. 끝.

자, 이번엔 홀수만 돌려주는 filter를 만들어 보도록 합시다.

먼저 홀수가 뭔지 생각해볼까요?

짝수는 2로 나누어 떨어지는 수이고, 홀수는 2로 나누어 떨어지지 않는 수입니다.

짝수를 2로 나눈 나머지는 0이고, 홀수를 2로 나누면 나머지가 1이죠.

또, 나머지를 구할 땐 %라는 연산자를 쓰면 됩니다. 예를 들어서, 50을 8로 나누면 몫은 6이고 나머지는 2니까 50%8은 2가 되는 거지요.

이제 홀수를 돌려주는 필터를 만들어 보겠습니다.

>>> filter(lambda x: x % 2, range(10))        # 파이썬 2
[1, 3, 5, 7, 9]  
>>> list(filter(lambda x: x % 2, range(10)))  # 파이썬 2 및 파이썬 3
[1, 3, 5, 7, 9]

지난 시간에 '참'은 1이고 '거짓'은 0이라고 했죠? 위의 filter 함수를 실행시키면,

0을 2로 나눈 나머지는 0이니까 람다 함수의 결과값은 0이고, 0은 '거짓'이니까 버려집니다.

1을 2로 나눈 나머지는 1이니까 람다 함수의 결과값은 1이고, 1은 '참'이니까 통과하지요.

이런 식으로 수행하면서 홀수만 돌려주게 되는 거지요.

휴~ 이번 강좌는 설명하기 힘들어서 쓰면서 한참 애먹었네요. 잘 이해되지 않는 부분이 있으면 질문답변 게시판에 올려주세요. 그럼 안녕~

마지막 편집일시 : 2013년 7월 13일 1:22:06 오전

댓글 28 피드백

마지막 %가 이해가 안되는데요 ㅠㅠ x를 2로 나눈 나머지는 무조건 1밖에 안나오는 것 아닌가요? 어떻게 1,3,5,7,9가 나오죠? x가 짝수일떈 나머지가 0, 홀수일땐 1 해서 [0,1]이 나와야되는거 아닌가요? - 포프, 2011년 2월 17일 11:38:35 오전
포프님, filter가 아닌 map(lambda x: x%2, range(10))을 하셨다면 결과가 [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]로 나오는 것이 맞아요. filter는 그 결과를 이용해서 목록을 한번 걸러주는 것이구요. - 최용, 2011년 2월 17일 12:14:13 오후
나누는 숫자를 달리해보니까 나머지가 0이 아닌 모든 값을 참으로 쳐서 거짓값만 걸러내는군요.. 짝수는 lambda x:(x+1)%2,...를 이용하면 되네요.. 친절한 설명감사드립니다 ㅎㅎ - 포프, 2011년 2월 21일 12:58:21 오후
참과 거짓을 이용해서 짝수, 홀수를 분별해 내는 거군요.  - dj, 2011년 3월 20일 5:04:45 오후
map(lambda x: x**2, range(5)) <map object at 0x00000000031FFCF8> <<<< 왜 이렇게 뜨는건가요 ? - ch, 2011년 4월 12일 11:57:44 오전
저두 그런디요 파이선3.2 사용하는데 문법이 변경된듯하네요 - xchrismas, 2011년 6월 14일 11:19:19 오후
@ch @xchrismas 파이썬3에 들어서는 list 함수를 써서 map과 filter를 목록으로 바꾸어주어야 합니다. 본문 수정했어요. 감사~ - 최용, 2011년 6월 15일 1:18:47 오전
하하 오늘 보니 업그레이드가 되어있네요 감사합니다. - xchrismas, 2011년 6월 15일 6:03:13 오후
해보면서 느낀점들. >>> def hap(x, y): ... return x + y 여기서 리턴 하라고한값을 출력하라고안했는데 hap(10,20)이 30으로 나온다는게 신기하네요 전 리턴할곳을 지정안했기때문에 안될거라 생각했어요 전 이렇게 해야될줄알았는데 def hap(x,y): c=x+y print c 그리도 또 신기햇던건 x+y=c print c는 안되더군요 초보라 다신기하네요.. 아그리고 질문이하나 있습니다. map과 람다를 이용 문자를 나오게할수있을까요 리스트가 레인지가 아닌 지정해둔 목록을 써서말이죠 예를 들면 목록에 아, 싸, 가, 오, 리 이렇게 지정해두었을때 함수를 써서 아!싸!가!오!리! 이런식으로 새로운 리스트가 나오게말이죠 맵과 람다를이용해서는 안될까요? - 잘보고있습니다., 2011년 6월 30일 10:03:39 오후
#['a','b','c','d'] or 'abcd' -> ['a!','b!','c!','d!'] def gaori(input_string,input_mark) : a=map(lambda x:x+input_mark,input_string) return a . . . #['a','b','c','d'] or 'abcd' -> 'a!b!c!d!' def gaori2(input_string,input_mark) : a=map(lambda x:x+input_mark,input_string) b=reduce(lambda x,y:x+y,a) return b - 화면가득, 2011년 7월 8일 3:04:26 오전
파이썬 처음배우면서 도움많이 받고있어요 ^^ 이번장은 따라가며 이해까진 했는데 응용을 잘 못하겠어요 본문내용중에 >>> map(lambda x: x**2, range(5)) [0, 1, 4, 9, 16] 이부분을 lambda 아니고 보통함수로 나타내는거는 어떻게 해야하나요? 나름대로 def이용해서 함수를 만들어서 map에 그 함수를 넣고 range(5)로 범위지정하려고 하는데 함수정의를 어떻게해야하는지 잘모르겠어요 제가만든건 def a(x): def a(): y=x**2 for x in a() return y x**2 return x 이렇게 두개로 만들었었거든요(앞장참고해서) 근데 다 꽝 이였어요 그리고 앞에 댓글에 글자에 ! 들어가게 만드는거 '화면가득'님이 답해주신거 해보니깐 안되던데 def로 카오리함수정의내린부분 입력하고 그다음 >>>나오고 난뒤에는 무얼입력해야하나요? 저는 gaori('abcde')이렇게입력했는데 여기서 잘못된건지 에러가나더라구요 - 꿀당고, 2012년 1월 9일 1:40:06 오전
꿀당고님, 제곱 함수는 제대로 만드셨네요. http://codepad.org/e27L2qWd 여기에 올렸으니 참고하세요. - 최용, 2012년 1월 9일 2:02:36 오후
저는 def로 함수만들면서 그안에서 다해야되는줄알았는데 저렇게 하는 방법이 있었군요 최용님 감사합니다 ^^ - 꿀당고, 2012년 1월 10일 4:13:54 오후
reduce(lambda x,y: y+x, 'abcde') 규칙 알것 같습니다. abcde bacde cabde dabce eabcd ebacd ecabd edabc edbac edcab edcba 이렇게 변하는것 같던데... - liveno, 2012년 1월 29일 11:19:26 오전
def hoho(stttt): a=map(lambda stttt:stttt ,'abcde') b='' for x in a: b=x+b print b - 신상리, 2012년 2월 8일 10:37:17 오전
근데 그 filter함수 홀수 구분하는 곳에서 filter(lambda x: x%2==1, range(10)) 이렇게 표현식에 등호같은게 있어야 참,거짓 구분가능한거 아닌가요? 그런 등호없이 어떻게 0 이 거짓이고 1이 참인걸 판단하죠? - 초짜, 2012년 2월 29일 11:29:09 오전
초짜님 말씀대로 등호 두 개를 써서 참/거짓을 판별하는 것도 맞는 방법입니다. 여기서는 0을 거짓으로 간주하는 파이썬의 특징을 이용해서 술수를 부려본 것이구요. - 최용, 2012년 2월 29일 12:52:17 오후
변하는 순서 알았어요.. (a)(b)cde - (ba)(c)de - (cba)(d)e - (dcba)(e) - (edcba) 즉 처음과 역순이 되었네요.. - 초보짱, 2012년 3월 27일 4:30:12 오후
와우~ - 화냐, 2012년 7월 11일 4:40:21 오후
abcde가 아마 이런식으로 변하는것 같네요 Y+X니까 B+A ->BA가 되죠 여기에 다시 C+BA ->CBA 여기에 D+CBA ->DCBA 여기에 E+DCBA->EDCBA가 되는것 같습니다 ㅎㅎ - 우와, 2012년 7월 17일 2:13:59 오후
reduce(lambda x,y: y+x, 'abcde') 의 규칙은 ba cba dcba edcba 아닌가요 ㅠ - 나모나키센시, 2013년 1월 15일 9:47:49 오전
filter(lambda x: x%2!=0, range(10)) - dd, 2013년 1월 28일 9:55:19 오전
자 제가 생각하기론 짝수는 걍 filter(lambda x:x%2==0,range(10)) 하시면 되구요, map 에 들어가는 리스트로 string 이 들어갔으니 ['a','b',ç','d',é'] 로 인식된 걸로 보여집니다. 더해지는 순서를 x+y가 아닌 y 가 x 의 앞으로 더해졌으므로 a ba cba dcba edcba 순으로 더해졌다고 보입니다.  - 왕초보, 2013년 2월 22일 12:04:25 오후
일반 def 을 사용하여 함수로 나타내면 power_ex(5) range is [0, 1, 2, 3, 4] [0, 1, 4, 9, 16] >>> def power_ex(x): print 'range is ', range(x) list0=list(range(x)) list1=[] for i in list0: y = i**2 list1.append(y) next print list1 - sj, 2013년 2월 26일 10:21:19 오후
reduce(lambda x,y: y+x, 'abcde') ...edcba -> a b c d e x y # x= ba -> c d e y # x= y+x =c+ba = cba -> d e y #x=cba=d+cba=dcba -> e y #x=dcba=e+dcba 결과적으로 edcba가 나오는거죠..... 작성자님께서 살짝 꼬아서 내신 포인트는ㅋㅋ reduce(lambda x,y: y+x, 'abcde') ...edcba reduce(lambda x,y: x+y, 'abcde') ...abcde 무슨 차이점인지 아시겠나요? y+x 와 x+y 의 차이 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 잘보고있습니다 ^^ - 2013start, 2013년 3월 15일 4:14:00 오후
일반함수로 나타내면 def listQ(): x=input('input= ') for y in range(x): print y**2 - JK, 2013년 4월 16일 8:01:41 오후
def inp(): x = int(raw_input('range input = ')) x = x - 1 while x >= 0 : xsq = x ** 2 xmenu.append(xsq) x -= 1 xmenu = [] i = inp() xmenu.sort() print xmenu TaeKyeong, 2014년 1월 8일 10:41:33 오전
reduce(lambda x, y, z: z + y + x, 'abcde') #error #TypeError: <lambda>() takes exactly 3 arguments (2 given) 요소가 두개인것만 되나보네요. 하나만 해도 안됨 반드시 두개 딱! Lilly, 2014년 2월 28일 9:04:15 오전

Dreamy의 코드 스크랩

내가 모으고 내가 보는

List of Articles
번호 분류 제목 날짜 조회 수 추천 수
240 Python python 내장 함수 2014.04.30 17574 0
239 Python map() 함수 2014.04.30 11310 0
238 PHP move_uploaded_file() 2014.04.29 11758 0
237 Python pylab - Plotting with Matplotlib 2014.04.28 11194 0
» Python Lambda 함수, 축약 함수 2014.04.25 13945 0
235 Python wxPython Tutorial 링크 2014.04.24 11958 0
234 Python distutils 개요 2014.04.24 10755 0
233 Python paramiko로 SSH 접속하기 2014.04.22 23069 0
232 일반 정규식 요약 프린트 file 2014.04.21 12189 0
231 LINUX Midnight Commander 간단 조작법 2014.04.07 12553 0
230 LINUX mc(Midnight Commander) 사용법 2 2014.04.07 19327 0
229 C# Ini 파일 작성과 사용하기 2014.04.03 18391 0
228 C# INI 파일 대신에 XML 로 설정값 저장/유지 하기 2014.04.03 14039 0
227 일반 cmd.exe 쉘 환경변수 추출 및 처리 2014.03.20 13072 0
226 일반 Visul Studio 2013 유용한 단축키 2014.03.01 27771 0
목록
Board Pagination ‹ Prev 1 ... 14 15 16 17 18 19 20 21 22 23 ... 34 Next ›
/ 34

나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소

Designed by sketchbooks.co.kr / sketchbook5 board skin

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5