{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "***\n", "***\n", "# 16. 람다 함수\n", "***\n", "***" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---\n", "## 1. 람다(lambda) 함수 정의\n", "---\n", "- 람다(lambda) 함수 (or 축약 함수): https://wikidocs.net/64\n", " - 일반적인 함수를 한 줄의 문(Statement)으로 정의할 수 있는 새로운 함수 정의 리터럴\n", " - 함수 몸체에는 식(expression)만이 올 수 있다. \n", " - 대부분의 경우 함수 이름을 정의하지 않으면서 일회성으로 활용할 함수를 정의할 때 활용\n", " - 구문(syntax)\n", " - lambda 콤마로 구분된 인수들: 식(expression)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1-1 람다 함수 정의 예" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 인수가 한 개 있는 람다 함수" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n" ] } ], "source": [ "f = lambda x: x + 1\n", "print f(1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 인수가 두 개 있는 람다 함수를 지니는 변수 지정 및 함수 호출" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n" ] } ], "source": [ "g = lambda x, y: x + y\n", "print g(1, 2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 기본 인수를 지니는 람다 함수 정의" ] }, { "cell_type": "code", "execution_count": 99, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "11\n", "15\n" ] } ], "source": [ "incr = lambda x, inc = 1: x + inc\n", "print incr(10) #inc 기본 인수 값으로 1 사용\n", "print incr(10, 5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 가변 인수를 지니는 람다 함수 정의" ] }, { "cell_type": "code", "execution_count": 100, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(2, 3, 4, 5)\n" ] } ], "source": [ "vargs = lambda x, *args: args\n", "print vargs(1,2,3,4,5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1-2 람다 함수 사용하기" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[60, 44, 30, 18, 8, 0, -6, -10, -12, -12, -10, -6, 0, 8, 18, 30, 44, 60, 78, 98]\n", "[-1000, -729, -512, -343, -216, -125, -64, -27, -8, -1, 0, 1, 8, 27, 64, 125, 216, 343, 512, 729]\n" ] } ], "source": [ "def f1(x):\n", " return x*x + 3*x - 10\n", "\n", "def f2(x):\n", " return x*x*x\n", "\n", "def g(func):\n", " return [func(x) for x in range(-10, 10)]\n", "\n", "print g(f1)\n", "print g(f2)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[60, 44, 30, 18, 8, 0, -6, -10, -12, -12, -10, -6, 0, 8, 18, 30, 44, 60, 78, 98]\n", "[-1000, -729, -512, -343, -216, -125, -64, -27, -8, -1, 0, 1, 8, 27, 64, 125, 216, 343, 512, 729]\n" ] } ], "source": [ "def g(func):\n", " return [func(x) for x in range(-10, 10)]\n", "\n", "print g(lambda x: x*x + 3*x - 10)\n", "print g(lambda x: x*x*x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 람다 함수를 사용하는 코드 예제" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0. add\n", "1. sub\n", "2. mul\n", "3. div\n", "4. quit\n" ] } ], "source": [ "# 더하기, 빼기, 곱하기, 나누기에 해당하는 람다 함수 리스트 정의\n", "func = [lambda x, y: x + y, lambda x, y: x - y, lambda x, y: x * y, lambda x, y: x / y]\n", "\n", "def menu():\n", " print \"0. add\"\n", " print \"1. sub\"\n", " print \"2. mul\"\n", " print \"3. div\"\n", " print \"4. quit\"\n", " return input('Select menu:')\n", "\n", "while 1:\n", " sel = menu() \n", " if sel < 0 or sel > len(func): \n", " continue\n", " if sel == len(func): \n", " break\n", " x = input('First operand:') \n", " y = input('Second operand:') \n", " print 'Result =', func[sel](x,y) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***\n", "## 2 람다 함수의 활용\n", "***\n", "- map, filter, reduce 내장 함수\n", " - 첫번째 인자: function\n", " - 첫번째 일반적으로 람다 함수를 인자로 받는다.\n", " - 두번째 인자: 시퀀스 자료형 (문자열, 리스트, 튜플)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2-1 map 내장 함수\n", "- map(function, seq)\n", " - seq 시퀀스 자료형이 지닌 각 원소값들에 대해 function에 적용한 결과를 동일 시퀀스 자료형으로 반환한다." ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 4, 9, 16, 25]\n" ] } ], "source": [ "def f(x):\n", " return x * x\n", "\n", "X = [1, 2, 3, 4, 5]\n", "Y = map(f, X)\n", "print Y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- map 내장 함수를 사용하지 않을 때 코드" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 4, 9, 16, 25]\n" ] } ], "source": [ "def f(x):\n", " return x * x\n", "\n", "X = [1, 2, 3, 4, 5]\n", "Y = []\n", "for x in X:\n", " y = f(x)\n", " Y.append(y)\n", "print Y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- map과 람다 함수를 동시에 사용하는 코드 (가장 추천하는 코드)" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 4, 9, 16, 25]\n" ] } ], "source": [ "X = [1, 2, 3, 4, 5]\n", "print map(lambda x: x * x, X)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- range(10)의 모든 값 x에 대해 f = x \\* x + 4 * x + 5의 계산 결과를 리스트로 구함" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[5, 10, 17, 26, 37, 50, 65, 82, 101, 122]\n" ] } ], "source": [ "Y = map(lambda x: x * x + 4 * x + 5, range(10))\n", "print Y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 각 단어들의 길이 리스트" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[5, 6, 11]\n" ] } ], "source": [ "y = map(lambda x: len(x), [\"Hello\", \"Python\", \"Programming\"])\n", "print y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2-2 filter 내장 함수\n", "- filter(function, seq)\n", " - seq 시퀀스 자료형이 지닌 각 원소값들에 대해 function에 적용한 결과가 참인 원소값들만을 동일 시퀀스 자료형으로 반환한다." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print filter(lambda x: x > 2, [1, 2, 3, 34])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 위 코드는 아래와 동일하다." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[3, 34]\n" ] } ], "source": [ "y = []\n", "for x in [1, 2, 3, 34]:\n", " if x > 2:\n", " y.append(x)\n", "print y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 주어진 시퀀스 내에 있는 정수중 홀수만 필터링" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print filter(lambda x: x % 2, [1, 2, 3, 4, 5, 6])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 주어진 시퀀스 내에 있는 정수중 짝수만 필터링" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "print filter(lambda x: x % 2 - 1, [1, 2, 3, 4, 5, 6])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 특정 범위에 있는 정수만 필터링" ] }, { "cell_type": "code", "execution_count": 77, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[2, 3, 4]\n" ] } ], "source": [ "def F():\n", " x = 1\n", " print filter(lambda a: a > x, range(-5, 5))\n", " \n", "F()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- filter의 결과는 주어진 seq 자료형과 동일함" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[3, 34]\n", "(3, 34)\n", "ABCDEF\n" ] } ], "source": [ "print filter(lambda x: x > 2, [1, 2, 3, 34])\n", "print filter(lambda x: x > 2, (1, 2, 3, 34))\n", "print filter(lambda x: x < 'a', 'abcABCdefDEF')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2-4 reduce 내장 함수\n", "- reduce (function, seq[, initial])\n", " - seq 시퀀스 자료형이 지닌 원소값들에 대해 function 함수를 적용하면서 하나의 값으로 매핑한다.\n", " - 첫번째 인자인 function 함수는 반드시 두 개의 인자 (예를 들어, x, y)를 받아야 한다.\n", " - seq 시퀀스 자료형의 각 원소값들은 각 단계별로 y에 순차적으로 들어간다. \n", " - 함수가 수행된 값은 각 단계별로 x에 순차적으로 들어간다.\n", " - 추가적으로 제공가능한 세번째 인자인 initial은 첫번째 단계에 x에 할당할 초기값으로 사용된다. " ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "15\n" ] } ], "source": [ "print reduce(lambda x, y: x + y, [1, 2, 3, 4, 5])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "| 단계 | x | y | reduce |\n", "|-----|---|---|---------|\n", "| 1 | 0 | 1 | 1 |\n", "| 2 | 1 | 2 | 3 |\n", "| 3 | 3 | 3 | 6 |\n", "| 4 | 6 | 4 | 10 |\n", "| 5 | 10| 5 | 15 | " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- initial 값 할당" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "115\n" ] } ], "source": [ "print reduce(lambda x, y: x + y, [1, 2, 3, 4, 5], 100)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 1부터 10까지 각 수에 대한 제곱값을 모두 더한 결과 구함" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "385\n" ] } ], "source": [ "print reduce(lambda x, y: x + y * y, range(1, 11), 0)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "385\n" ] } ], "source": [ "x = 0\n", "for y in range(1, 11):\n", " x = x + y * y\n", "print x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 문자열 순서 뒤집기" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "edcba\n" ] } ], "source": [ "print reduce(lambda x, y: y + x, 'abcde')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "| 단계 | x | y | reduce |\n", "|-----|---|---|---------|\n", "| 1 | '' | 'a' | 'a' |\n", "| 2 | 'a' | 'b' | 'ba' |\n", "| 3 | 'ba' | 'c' | 'cba' |\n", "| 4 | 'cba' | 'd' | 'dcba' |\n", "| 5 | 'dcba' | 'e' | 'edcba' | " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

참고 문헌: 파이썬(열혈강의)(개정판 VER.2), 이강성, FreeLec, 2005년 8월 29일

" ] } ], "metadata": {}, "nbformat": 4, "nbformat_minor": 0 }