{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 函数" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在大部分时候,在一个算法中,需要重复执行一组语句,如果每次都重复写出来,不仅乏味而且编程效率比较低,降低程序的可读性。为了将重复的执行抽象出来,可使用函数将一组操作封装成一个整体,给一个名称和参数列表作为可变量的输入。Python中函数的定义为:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```\n", "def funcname(arg1, arg2,... argN):\n", " \n", " ''' Document String'''\n", "\n", " statements\n", "\n", "\n", " return \n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "将上面的语法理解为,定义了一个名为`funcname`的函数,它接受`arg1,arg2,…argN`的参数。函数在执行语句后返回一个``。" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hey Jack!\n", "Jack, How do you do?\n" ] } ], "source": [ "print(\"Hey Jack!\")\n", "print(\"Jack, How do you do?\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "不需要每次都写上面的两个语句,可以通过定义一个函数来替换它,这个函数只需一行就能完成任务。\n", "\n", "定义一个函数 `first_func()`." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def first_func():\n", " print(\"Hey Jack!\")\n", " print(\"Jack, How do you do?\")" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hey Jack!\n", "Jack, How do you do?\n", "Hey Jack!\n", "Jack, How do you do?\n" ] } ], "source": [ "first_func()\n", "funca=first_func\n", "funca()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**first_func()** 每一次只打印一个人的消息。我们可以让我们的函数 **first_func()** 接受参数,该参数将存储名称然后打印相应地接受字符串。为了这样做我们需要像所示的那样在函数内添加一个参数。" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def first_func(username):\n", " print(\"Hey\", username + '!')\n", " print(username + ',' ,\"How do you do?\")" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Please enter your name : Python\n" ] } ], "source": [ "name1 = input('Please enter your name : ')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "名称“Willam”实际上存储在name1中。我们将这个变量传递给函数**firstfunc()** 作为变量username,因为它是为这个函数定义的变量。即name1作为用户名传递。" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hey Python!\n", "Python, How do you do?\n" ] } ], "source": [ "first_func(name1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "让我们通过定义另一个函数**second_func()** 来进一步简化它,该函数接受名称并将其存储在一个变量中,然后从函数本身内部调用**first_func()**。" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def first_func(username):\n", " print(\"Hey\", username + '!')\n", " print(username + ',' ,\"How do you do?\")\n", "def second_func():\n", " name = input(\"Please enter your name : \")\n", " first_func(name)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Please enter your name : Tom\n", "Hey Tom!\n", "Tom, How do you do?\n" ] } ], "source": [ "second_func()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1. 返回语句" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "当函数产生某个值,并且该值必须存储在一个变量中,或者需要返回或返回给主算法进行进一步操作时,使用return语句。" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def times(x,y):\n", " z = x*y\n", " return z" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "上面定义的**times()** 函数接受两个参数并返回变量z,该变量包含两个参数的乘积结果。" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "20\n" ] } ], "source": [ "c = times(4,5)\n", "print(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "z值存储在变量c中,可以用于进一步的操作。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "可以在return语句中使用整个语句本身,而不是声明另一个变量,如下所示。" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def times(x,y):\n", " '''This multiplies the two input arguments'''\n", " return x*y" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "20\n" ] } ], "source": [ "c = times(4,5)\n", "print(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "由于现在定义了**times()**,我们可以如上所示记录它。在**help()** 函数下调用**times()** 函数时返回该文档。" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on function times in module __main__:\n", "\n", "times(x, y)\n", " This multiplies the two input arguments\n", "\n" ] } ], "source": [ "help(times)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": true }, "outputs": [], "source": [ "times?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "也可以返回多个变量,但请记住顺序。" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": true }, "outputs": [], "source": [ "eglist = [10,50,30,12,6,8,100]" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def egfunc(eglist):\n", " highest = max(eglist)\n", " lowest = min(eglist)\n", " first = eglist[0]\n", " last = eglist[-1]\n", " return highest,lowest,first,last" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "如果调用函数时没有为其分配任何变量,则结果将在一个元组中返回。但是如果变量被提到了,那么结果会以特定的顺序分配给变量,这个顺序在return语句中声明。" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(100, 6, 10, 100)\n" ] } ], "source": [ "a = egfunc(eglist)\n", "print(a)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " a = 100 \n", " b = 6 \n", " c = 10 \n", " d = 100\n" ] } ], "source": [ "a,b,c,d = egfunc(eglist)\n", "print(' a =',a,'\\n b =',b,'\\n c =',c,'\\n d =',d)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2. 隐式参数" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "当一个函数的参数在大多数情况下是常见的或者它是`隐式的`时,使用这个概念。" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def implicit_add(x, addnumber=3):\n", " return x+addnumber" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**implicit_add( )** 是一个函数接受两个参数,但大多数时候第一个参数只需要加3。因此,第二个参数被赋值为3。这里第二个参数是隐式的。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "现在,如果在调用**implicit_add()** 函数时没有定义第二个参数,则将其视为3。" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "7" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "implicit_add(4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "但如果指定了第二个参数,则此值将覆盖分配给该参数的隐式值" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "8" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "implicit_add(4,4)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "11" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "implicit_add(5, addnumber=6)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. 任意数量的参数" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "如果函数要接受的参数数量未知,则在参数前使用星号。" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def add_n(*args):\n", " res = 0\n", " reslist = []\n", " for i in args:\n", " reslist.append(i)\n", " print(reslist)\n", " return sum(reslist)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "上面的函数接受任意数量的参数,定义一个列表,并将所有参数附加到该列表中,并返回所有参数的总和。" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3, 4, 5]\n" ] }, { "data": { "text/plain": [ "15" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "add_n(1,2,3,4,5)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3]\n" ] }, { "data": { "text/plain": [ "6" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "add_n(1,2,3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "参数列表也可以通过 \"param_name = value\" 的形式传入到函数" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[30, 10, 20]\n" ] }, { "data": { "text/plain": [ "60" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def add_nd(**kwargs):\n", " res = 0\n", " reslist = []\n", " for (k,v) in kwargs.items():\n", " reslist.append(v)\n", " print(reslist)\n", " return sum(reslist)\n", "\n", "add_nd(x=10, y=20, c=30)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4. 全局和局部变量" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在函数内部声明的变量是局部变量,生命周期限于函数执行期间;在函数外部声明的是全局变量。" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": true }, "outputs": [], "source": [ "eg1 = [1,2,3,4,5]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在下面的函数中,我们将在函数内部声明的列表中追加一个元素。函数内部声明的eg2变量是一个局部变量。" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def egfunc1():\n", " eg1 = [1, 2, 3, 4, 5, 7]\n", " print(\"egfunc1>> eg1: \", eg1)\n", "\n", "def egfunc2():\n", " eg1.append(8)\n", " print(\"egfunc2>> eg1: \", eg1)\n", "\n", "def egfunc3():\n", " global eg1\n", " eg1 = [5, 4, 3, 2, 1]\n", " print(\"egfunc3>> eg1: \", eg1)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "egfunc1>> eg1: [1, 2, 3, 4, 5, 7]\n", "eg1: [1, 2, 3, 4, 5] \n", "\n", "egfunc2>> eg1: [1, 2, 3, 4, 5, 8]\n", "eg1: [1, 2, 3, 4, 5, 8] \n", "\n", "egfunc3>> eg1: [5, 4, 3, 2, 1]\n", "eg1: [5, 4, 3, 2, 1] \n", "\n" ] } ], "source": [ "egfunc1()\n", "print(\"eg1: \", eg1, \"\\n\")\n", "\n", "egfunc2()\n", "print(\"eg1: \", eg1, \"\\n\")\n", "\n", "egfunc3()\n", "print(\"eg1: \", eg1, \"\\n\")\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5. Lambda 函数" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "程序中有时需要临时使用一个简单的函数,单独定义出来比较费事,为了提高编程效率,Python等很多语言引入了`Lambda`函数,这些Lambda函数没有使用任何名称定义,只携带一个表达式,返回的是函数本身(类似函数指针或者函数对象)。Lambda函数在操作列表时非常方便。这些函数由关键字**lambda**定义,后面跟着变量、冒号和相应的表达式。" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": true }, "outputs": [], "source": [ "z = lambda x: x * x" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "64" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "z(8)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(6, 8)" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "zz = lambda x, y: (x*y, x**y)\n", "zz(2, 3)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "function" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "type(z)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "function" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "def sqr(x):\n", " return x*x\n", "\n", "type(sqr)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5.1 map" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**map( )** 函数主要执行分别为列表的每个元素定义的函数。" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "collapsed": true }, "outputs": [], "source": [ "list1 = [1,2,3,4,5,6,7,8,9]" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[3, 4, 5, 6, 7, 8, 9, 10, 11]\n" ] } ], "source": [ "eg = map(lambda x:x+2, list1)\n", "print(list(eg))" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 4, 9, 16, 25, 36, 49, 64, 81]\n" ] } ], "source": [ "eg = map(sqr, list1)\n", "print(list(eg))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "你也可以添加两个列表。" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": true }, "outputs": [], "source": [ "list2 = [9,8,7,6,5,4,3,2,1]" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[10, 10, 10, 10, 10, 10, 10, 10, 10]\n" ] } ], "source": [ "eg2 = map(lambda x,y:x+y, list1,list2)\n", "print(list(eg2))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "不仅可以使用lambda函数,还可以使用其他内建函数。" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "eg3 = map(str,eg2)\n", "print(eg3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 5.2 filter" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**filter( )** 函数用于过滤列表中的值。 注意 **filter()** 函数返回一个新列表中的结果。" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "collapsed": true }, "outputs": [], "source": [ "list1 = [1,2,3,4,5,6,7,8,9]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "为了得到小于5的元素。" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 3, 4]\n" ] } ], "source": [ "res = filter(lambda x:x<5,list1)\n", "print(list(res))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "注意当使用**map()** 时会发生什么" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "map(lambda x:x<5, list1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "我们可以得出这样的结论,在**map()** 函数中返回的值为真,在使用**filter()** 函数时将返回特定的元素。" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "filter(lambda x:x%4==0,list1)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.4" } }, "nbformat": 4, "nbformat_minor": 1 }