{
    "componentChunkName": "component---src-templates-blog-post-js",
    "path": "/19-12-10-lambda-expression/",
    "result": {"data":{"site":{"siteMetadata":{"title":"irrationnelle","author":"irrationnelle","siteUrl":"https://dev.rase.blog","comment":{"disqusShortName":"","utterances":"irrationnelle/devlog"},"sponsor":{"buyMeACoffeeId":""}}},"markdownRemark":{"id":"18ba2867-f601-5f86-b532-47af96a5af05","excerpt":"개발을 공부하다보면 ‘문(statement)‘이라는 말을 많이 사용한다. 조건문 또는 if문, 반복문 또는 for문 이렇게. 그런데 가끔씩 ‘식(expression)’ 이라는 표현을 쓸 때도 있다. 람다식(lambda expression)이 그 중 하나이다. statement 와 expression 식과 문을 비교하는 좋은 글들이 많이 있기 때문에 여기서는 간단하게 이야기한다. 식은 결과값이 나올 때 식이라고 한다. 3 이라는 단일 리터럴 변수는 정수 타입의 3 이라는 결과값이 있다. 3+…","html":"<p>개발을 공부하다보면 ‘문(statement)‘이라는 말을 많이 사용한다. 조건문 또는 if문, 반복문 또는 for문 이렇게.</p>\n<p>그런데 가끔씩 ‘식(expression)’ 이라는 표현을 쓸 때도 있다. 람다식(lambda expression)이 그 중 하나이다.</p>\n<h1 id=\"statement-와-expression\" style=\"position:relative;\"><a href=\"#statement-%EC%99%80-expression\" aria-label=\"statement 와 expression permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>statement 와 expression</h1>\n<p>식과 문을 비교하는 좋은 글들이 많이 있기 때문에 여기서는 간단하게 이야기한다.</p>\n<p>식은 결과값이 나올 때 식이라고 한다. 3 이라는 단일 리터럴 변수는 정수 타입의 3 이라는 결과값이 있다. 3+5 는 정수 타입의 8이라는 결과값이 나온다.</p>\n<p>반면 문은 코드 실행을 하는데 의미를 가진 최소 단위이다. <code class=\"language-text\">if tyloIsHandsome: wakeUp()</code> 는 어떤 조건이 있고 그 조건을 만족하면 다음 함수를 실행시키겠다는 의미를 가지고 있지만 어떤 결과값이 나오진 않는다. 오해할 수 있는 것이 할당<em>문</em> 처럼 <code class=\"language-text\">num = 10</code> 이라고 되어있는 것도 num 이라는 변수에 10을 할당하겠다는 의미이지, <code class=\"language-text\">num = 10</code> 자체가 결과값은 아니다.</p>\n<p>한 가지 더, 다음 코드를 보자</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">def</span> <span class=\"token function\">to_be_four</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> <span class=\"token number\">4</span></code></pre></div>\n<p>위의 함수 정의에서 <code class=\"language-text\">return 4</code> 역시 <code class=\"language-text\">statement</code> 이지 4라는 결과값을 가지는 <code class=\"language-text\">expression</code>이 아니다. 하지만 다음처럼 함수를 호출하는 건 <code class=\"language-text\">expression</code> 이다. 함수 호출의 결과로 4가 나오기 때문에.</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\">to_be_four<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token comment\"># 이 함수를 호출하면 4 가 나오고, 호출 결과는 리터럴값인 4와 동일한 의미를 가진다.</span></code></pre></div>\n<p>그리고 이 포스팅의 메인 게스트인 <code class=\"language-text\">lambda</code> 는 <code class=\"language-text\">expression</code> 이다. 그래서 <em>람다식</em>이라고 부르기도 한다.</p>\n<p>참고로 젯브래인 사에서 만든 코틀린이라는 언어에서는 <code class=\"language-text\">if expression</code> 이라는 게 존재한다. 관심가면 알아보자.</p>\n<h1 id=\"lambda-expression\" style=\"position:relative;\"><a href=\"#lambda-expression\" aria-label=\"lambda expression permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>lambda expression</h1>\n<p>다음은 공식 문서에서 람다함수를 설명하는 글이다.</p>\n<blockquote>\n<p>Small anonymous functions can be created with the lambda keyword. This function returns the sum of its two arguments: <code class=\"language-text\">lambda a, b: a+b</code>. Lambda functions can be used wherever function objects are required. They are syntactically restricted to a single expression. Semantically, they are just <strong>syntactic sugar</strong> for a normal function definition. Like nested function definitions, lambda functions can <strong>reference variables from the containing scope</strong></p>\n</blockquote>\n<p>공식 문서에 한글 버전도 있지만 번역이 교과서적으로 밋밋하게 되어 있어 원문을 가져왔다.</p>\n<p>람다식은 결국 일반적인 함수 정의의 <em>문법적 설탕(syntactic sugar)</em> 이라는 표현이 있는데, 문법적 설탕이라는 건 굳이 이 문법을 쓰지 않아도 괜찮지만 이 문법을 쓴다면 좀 더 편하게 코드 작성을 할 수 있다는 것을 의미한다.</p>\n<p>파이썬에서는 변수에 온갖 것들을 담을 수 있다. 함수도 그 중 하나인데, 즉 이런 게 가능하다.</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">def</span> <span class=\"token function\">add_numbers</span><span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">,</span>b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> a<span class=\"token operator\">+</span>b\n\nfun_var <span class=\"token operator\">=</span> add_numbers <span class=\"token comment\"># 이건 변수에다 '함수 자체'를 할당한다.</span>\nfun_value <span class=\"token operator\">=</span> add_numbers<span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span><span class=\"token number\">2</span><span class=\"token punctuation\">)</span> <span class=\"token comment\"># 이건 변수에다 '함수가 반환하는 값'을 할당한다.</span>\n\nresult <span class=\"token operator\">=</span> fun_var<span class=\"token punctuation\">(</span><span class=\"token number\">3</span><span class=\"token punctuation\">,</span><span class=\"token number\">4</span><span class=\"token punctuation\">)</span> <span class=\"token comment\"># fun_var 는 함수 자체를 담았기 때문에 그 함수처럼 사용이 가능하다.</span>\n\n<span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>fun_value<span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">)</span></code></pre></div>\n<p>변수에 함수를 담을 수 있다는 것은 매개변수에도 함수를 담을 수 있다는 거고, 따라서 함수의 인자로 함수를 전달하는 것도 가능하다.</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">def</span> <span class=\"token function\">just_print</span><span class=\"token punctuation\">(</span>other_fun<span class=\"token punctuation\">,</span> <span class=\"token operator\">*</span>args<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>other_fun<span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>args<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    \n<span class=\"token keyword\">def</span> <span class=\"token function\">add_numbers</span><span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> a<span class=\"token operator\">+</span>b\n\njust_print<span class=\"token punctuation\">(</span>add_numbers<span class=\"token punctuation\">,</span> <span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>이런 일들이 가능하기 때문에 람다식이 문법적 설탕으로 불리우는 것이다. 람다식이라는 건 <a href=\"https://ko.wikipedia.org/wiki/%EB%9E%8C%EB%8B%A4_%EB%8C%80%EC%88%98\">람다대수</a> 라는 개념에서 온 것인데, 자바같은 언어에서는 변수에다가 함수를 담는 것도 안 되고, 함수의 인자로 함수를 보내는 것이 안 된다. 이게 별거 아닌 거 같지만 굉장히 짜증스럽고 코드를 복잡하게 늘어놔야 하는 일들이 많기 때문에 굉장히 불편했는데 자바8부터 람다식을 지원해줘서 조금 숨통이 트이게 되었다.</p>\n<p>여기까지 이야기했다면 람다식이 무엇인지 대충 감이 올 수도 있다. 위의 예시 코드들을 다시 람다식을 이용해서 바꿔보자</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\">fun_var <span class=\"token operator\">=</span> <span class=\"token keyword\">lambda</span> x<span class=\"token punctuation\">,</span> y<span class=\"token punctuation\">:</span> x<span class=\"token operator\">+</span>y \n\nresult <span class=\"token operator\">=</span> fun_var<span class=\"token punctuation\">(</span><span class=\"token number\">3</span><span class=\"token punctuation\">,</span><span class=\"token number\">4</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>result<span class=\"token punctuation\">)</span></code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">from</span> functools <span class=\"token keyword\">import</span> <span class=\"token builtin\">reduce</span>\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">just_print</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>args<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">reduce</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">lambda</span> x<span class=\"token punctuation\">,</span> y<span class=\"token punctuation\">:</span> x<span class=\"token operator\">+</span>y<span class=\"token punctuation\">,</span> args<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    \njust_print<span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span>\njust_print<span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> <span class=\"token number\">3</span><span class=\"token punctuation\">)</span>\njust_print<span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">,</span> <span class=\"token number\">5</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>막상 코드를 작성하니까 <code class=\"language-text\">reduce</code> 같은 키워드도 나와버렸다. 아직은 생소한 <code class=\"language-text\">reduce</code> 까지 사용하면서 바꾼 코드로 보여주고 싶었던 점은</p>\n<blockquote>\n<p>람다식은 익명 함수이다. 즉 함수명이 없다.</p>\n</blockquote>\n<p>앞서서 사용했던 예시에는 <code class=\"language-text\">def</code> 키워드를 이용하여 함수들에게 이름을 지정해주었다. 하지만 람다식에는 함수 이름이 없다. <code class=\"language-text\">fun_var = lambda x, y: x+y</code>를 보고 <code class=\"language-text\">fun_var</code> 가 이 람다식의 이름이 아니냐고 생각할 수 있지만, 어디까지나 <code class=\"language-text\">fun_var</code> 라는 변수에 람다식을 할당한 것이지 람다식의 이름을 지어준 것이 아니다.</p>\n<p>이렇게 람다식을 사용하면 함수를 구태여 정의하지 않고 좀 더 직관적인 방법으로 함수를 변수에 담거나 다른 함수의 인자로 사용할 수 있다. 당장 위의 예시에서 람다식은 <code class=\"language-text\">reduce</code> 함수의 첫번째 인자로 사용된 것을 알 수 있다.</p>\n<p>뭐 익명함수이기 때문에 함수 사용이 끝나고 나면 heap 영역을 점유하고 있던 메모리를 가비지 컬렉터가 수거해가고 어쩌고 같은 이야기도 있지만 아직은 크게 신경쓰지 않아도 좋다.</p>\n<h1 id=\"마치며\" style=\"position:relative;\"><a href=\"#%EB%A7%88%EC%B9%98%EB%A9%B0\" aria-label=\"마치며 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>마치며</h1>\n<p>람다식, 또는 함수를 인자로 보내는 개념은 리스트를 다룰 때, <a href=\"https://docs.python.org/3/tutorial/datastructures.html#list-comprehensions\">list comprehension</a> 와 map, filter 를 사용할 때 좀 더 와닿는다. 또한 map 을 사용할 때는 <code class=\"language-text\">지연 평가(lazy evaluation)</code> 와 <code class=\"language-text\">제네레이터</code> 라는 개념을 접할 수 있는데, 아주 흥미로운 부분이다. 이 방법들은 파이썬을 사용하는 사람들간의 의견 차이가 있는 편인데 그 또한 굉장히 흥미로우니 관심있는 사람은 아래의 글을 읽어보도록 하자.</p>\n<p><a href=\"https://stackoverflow.com/questions/1247486/list-comprehension-vs-map\">List comprehension vs map</a></p>","frontmatter":{"title":"lambda expression","date":"December 10, 2019"}}},"pageContext":{"slug":"/19-12-10-lambda-expression/","previous":{"fields":{"slug":"/19-12-09-why-use-return-statement/"},"frontmatter":{"title":"return 을 사용하는 이유","category":"Python","draft":false}},"next":{"fields":{"slug":"/19-12-16-list-comprehension/"},"frontmatter":{"title":"list 이해하기","category":"Python","draft":false}}}},
    "staticQueryHashes": ["3128451518","3474900066"]}