一 数学定义的函数与python中的函数

初中数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因变量,y是x的函数。自变量x的取值范围叫做这个函数的定义域

例如y=2*x

python中函数定义:函数是逻辑结构化和过程化的一种编程方法

  1. 1 python中函数定义方法:
  2. 2
  3. 3 def test(x):
  4. 4 "The function definitions"
  5. 5 x+=1
  6. 6 return x
  7. 7
  8. 8 def:定义函数的关键字
  9. 9 test:函数名
  10. 10 ():内可定义形参
  11. 11 "":文档描述(非必要,但是强烈建议为你的函数添加描述信息)
  12. 12 x+=1:泛指代码块或程序处理逻辑
  13. 13 return:定义返回值
  1. 调用运行:可以带参数也可以不带
    函数名()

补充:

1.编程语言中的函数与数学意义的函数是截然不同的俩个概念,编程语言中的函数是通过一个函数名封装好一串用来完成某一特定功能的逻辑,数学定义的函数就是一个等式,等式在传入因变量值x不同会得到一个结果y,这一点与编程语言中类似(也是传入一个参数,得到一个返回值),不同的是数学意义的函数,传入值相同,得到的结果必然相同且没有任何变量的修改(不修改状态),而编程语言中的函数传入的参数相同返回值可不一定相同且可以修改其他的全局变量值(因为一个函数a的执行可能依赖于另外一个函数b的结果,b可能得到不同结果,那即便是你给a传入相同的参数,那么a得到的结果也肯定不同)

2.函数式编程就是:先定义一个数学函数(数学建模),然后按照这个数学模型用编程语言去实现它。至于具体如何实现和这么做的好处,且看后续的函数式编程。

二 为何使用函数

总结使用函数的好处:

1.代码重用

2.保持一致性,易维护

3.可扩展性

三 函数和过程

过程定义:过程就是简单特殊没有返回值的函数

这么看来我们在讨论为何使用函数的的时候引入的函数,都没有返回值,没有返回值就是过程,没错,但是在python中有比较神奇的事情

  1. 1 def test01():
  2. 2 msg='hello The little green frog'
  3. 3 print msg
  4. 4
  5. 5 def test02():
  6. 6 msg='hello WuDaLang'
  7. 7 print msg
  8. 8 return msg
  9. 9
  10. 10
  11. 11 t1=test01()
  12. 12
  13. 13 t2=test02()
  14. 14
  15. 15
  16. 16 print 'from test01 return is [%s]' %t1
  17. 17 print 'from test02 return is [%s]' %t2

总结:当一个函数/过程没有使用return显示的定义返回值时,python解释器会隐式的返回None,

所以在python中即便是过程也可以算作函数

  1. 1 def test01():
  2. 2 pass
  3. 3
  4. 4 def test02():
  5. 5 return 0
  6. 6
  7. 7 def test03():
  8. 8 return 0,10,'hello',['alex','lb'],{'WuDaLang':'lb'}
  9. 9
  10. 10 t1=test01()
  11. 11 t2=test02()
  12. 12 t3=test03()
  13. 13
  14. 14
  15. 15 print 'from test01 return is [%s]: ' %type(t1),t1
  16. 16 print 'from test02 return is [%s]: ' %type(t2),t2
  17. 17 print 'from test03 return is [%s]: ' %type(t3),t3

总结:

返回值数=0:返回None

返回值数=1:返回object

返回值数>1:返回tuple

四 函数参数

1.形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量

2.实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值

3.位置参数和关键字(标准调用:实参与形参位置一一对应;关键字调用:位置无需固定)

4.默认参数

5.参数组

五 局部变量和全局变量

在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。

全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
当全局变量与局部变量同名时:
在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。
  1. 1 name='lhf'
  2. 2
  3. 3 def change_name():
  4. 4 print('我的名字',name)
  5. 5
  6. 6 change_name()
  7. 7
  8. 8
  9. 9 def change_name():
  10. 10 name='帅了一笔'
  11. 11 print('我的名字',name)
  12. 12
  13. 13 change_name()
  14. 14 print(name)
  15. 15
  16. 16
  17. 17
  18. 18 def change_name():
  19. 19 global name
  20. 20 name='帅了一笔'
  21. 21 print('我的名字',name)
  22. 22
  23. 23 change_name()
  24. 24 print(name)

六 前向引用之'函数即变量'

  1. 1 def action():
  2. 2 print 'in the action'
  3. 3 logger()
  4. 4 action()
  5. 5 报错NameError: global name 'logger' is not defined
  6. 6
  7. 7
  8. 8 def logger():
  9. 9 print 'in the logger'
  10. 10 def action():
  11. 11 print 'in the action'
  12. 12 logger()
  13. 13
  14. 14 action()
  15. 15
  16. 16
  17. 17 def action():
  18. 18 print 'in the action'
  19. 19 logger()
  20. 20 def logger():
  21. 21 print 'in the logger'
  22. 22
  23. 23 action()

七 嵌套函数和作用域

看上面的标题的意思是,函数还能套函数?of course

  1. 1 name = "Alex"
  2. 2
  3. 3 def change_name():
  4. 4 name = "Alex2"
  5. 5
  6. 6 def change_name2():
  7. 7 name = "Alex3"
  8. 8 print("第3层打印",name)
  9. 9
  10. 10 change_name2() #调用内层函数
  11. 11 print("第2层打印",name)
  12. 12
  13. 13
  14. 14 change_name()
  15. 15 print("最外层打印",name)

此时,在最外层调用change_name2()会出现什么效果?

没错, 出错了, 为什么呢?

作用域在定义函数时就已经固定住了,不会随着调用位置的改变而改变

  1. 1 例一:
  2. 2 name='alex'
  3. 3
  4. 4 def foo():
  5. 5 name='lhf'
  6. 6 def bar():
  7. 7 print(name)
  8. 8 return bar
  9. 9
  10. 10 func=foo()
  11. 11 func()
  12. 12
  13. 13
  14. 14 例二:
  15. 15 name='alex'
  16. 16
  17. 17 def foo():
  18. 18 name='lhf'
  19. 19 def bar():
  20. 20 name='wupeiqi'
  21. 21 def tt():
  22. 22 print(name)
  23. 23 return tt
  24. 24 return bar
  25. 25
  26. 26 func=foo()
  27. 27 func()()

八 递归调用

古之欲明明德于天下者,先治其国;欲治其国者,先齐其家;欲齐其家者,先修其身;欲修其身者,先正其心;欲正其心者,先诚其意;欲诚其意者,先致其知,致知在格物。物格而后知至,知至而后意诚,意诚而后心正,心正而后身修,身修而后家齐,家齐而后国治,国治而后天下平。

在函数内部,可以调用其他函数。如果在调用一个函数的过程中直接或间接调用自身本身

  1. 1 def calc(n):
  2. 2 print(n)
  3. 3 if int(n/2) ==0:
  4. 4 return n
  5. 5 return calc(int(n/2))
  6. 6
  7. 7 calc(10)
  8. 8
  9. 9 输出:
  10. 10 10
  11. 11 5
  12. 12 2
  13. 13 1

递归特性:

1. 必须有一个明确的结束条件

2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少

3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

九 匿名函数

匿名函数就是不需要显式的指定函数

  1. 1 #这段代码
  2. 2 def calc(n):
  3. 3 return n**n
  4. 4 print(calc(10))
  5. 5
  6. 6 #换成匿名函数
  7. 7 calc = lambda n:n**n
  8. 8 print(calc(10))

你也许会说,用上这个东西没感觉有毛方便呀, 。。。。呵呵,如果是这么用,确实没毛线改进,不过匿名函数主要是和其它函数搭配使用的呢,如下

  1. 1 l=[3,2,100,999,213,1111,31121,333]
  2. 2 print(max(l))
  3. 3
  4. 4 dic={'k1':10,'k2':100,'k3':30}
  5. 5
  6. 6
  7. 7 print(max(dic))
  8. 8 print(dic[max(dic,key=lambda k:dic[k])])
  1. 1 res = map(lambda x:x**2,[1,5,7,4,8])
  2. 2 for i in res:
  3. 3 print(i)
  4. 4
  5. 5 输出
  6. 6 1
  7. 7 25
  8. 8 49
  9. 9 16
  10. 10 64

十 函数式编程

峰哥原创面向过程解释:

函数的参数传入,是函数吃进去的食物,而函数return的返回值,是函数拉出来的结果,面向过程的思路就是,把程序的执行当做一串首尾相连的函数,一个函数吃,拉出的东西给另外一个函数吃,另外一个函数吃了再继续拉给下一个函数吃。。。

例如:
用户登录流程:前端接收处理用户请求-》将用户信息传给逻辑层,逻辑词处理用户信息-》将用户信息写入数据库
验证用户登录流程:数据库查询/处理用户信息-》交给逻辑层,逻辑层处理用户信息-》用户信息交给前端,前端显示用户信息

十一 高阶函数

满足俩个特性任意一个即为高阶函数

1.函数的传入参数是一个函数名

2.函数的返回值是一个函数名

简单例子:

  1. f = abs # 这就表示Python中函数名是可以传送给变量的
  2. print(f(-9))
  3.  
  4. def add(a,b,f):
  5. return f(a)+f(b)
  6.  
  7. print(add(1,2,abs)) # 如果将函数名传入为另一个函数参数,这样的叫做高阶函数

常见高阶函数使用

1. map函数

  • map函数:map函数是相当于通过一个函数将输入变量一一映射(通过某类函数)进行输出。map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回
  1. def fuc(x):
  2. return x*x
  3.  
  4. r = map(fuc,[1,2,3])
  5. print(list(r))

为什么需要map这样的函数了? 因为map函数第一个参数是作用的函数,我们可以通过这个函数清楚的知道这个函数具体的作用是什么,起到了见名知意的作用

  1. >>> map(str,[1,2,3,4,5])
  2. <map object at 0x00000219AAD1C5F8>
  3. >>> list(map(str,[1,2,3,4,5]))
  4. ['', '', '', '', '']

2. reduce函数:

  • reduce把一个函数作用在一个序列[x1, x2, x3, …]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
  1. from functools import reduce
  2. def add(a,b):
  3. return a+b
  4.  
  5. print(reduce(add,[1,2,3,4])) # 使用redunce这里相当于是sum
  6.  
  7. def add1(a,b):
  8. return 10 * a + b
  9. print(reduce(add1,[1,2,3,4])) # 这个例子相当于是进行迭代操作,一次一次进行迭代
  10. 1
  11. 2
  12. 3
  13. 4
  14. 5
  15. 6
  16. 7
  17. 8
  18. 9
  19. >>> from functools import reduce
  20. >>> def fn(x, y):
  21. return x * 10 + y
  22. ...
  23. >>> def char2num(s):...
  24. digits = {'': 0, '': 1, '': 2, '': 3, '': 4, '': 5, '': 6, '': 7, '': 8, '': 9}
  25. ... return digits[s]
  26. ...
  27. >>> reduce(fn, map(char2num, ''))
  28. 13579

3. filter()函数

Python内建的filter()函数用于过滤序列。和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。所以filter和map区别一点就是filter就像滤波器一样会保留或者丢掉一些元素,但是map是不会丢弃元素的,只是会作用在一些元素上面的。

  1. def is_odd(num):
  2. #if(num%2==1):
  3. # return num
  4. return num % 2 == 1 # 这句话的含义就是先进行判断然后进行合适数字的输出
  5. print(list(filter(is_odd, [1, 2, 3, 4, 5, 6]))) # filter和map类似的,输出的也是一个惰性序列,需要通过List强制进行转换

* 注意到filter()函数返回的是一个Iterator,也就是一个惰性序列,所以要强迫filter()完成计算结果,需要用list()函数获得所有结果并返回list。*

4. sorted()排序函数

  • sort函数直接可以作用于list中,表示对其进行排序,sorted函数也是一个高阶函数,里面也是可以传入其他的参数
  1. print(sorted([1, 2, 49, -11])) # 默认是从小到大进行排序
  2. print(sorted([1, 2, 49, -11], reverse=True)) # 通过reverse属性,表示我们使用反向排序,也就是从大到小进行排序
  3. print(sorted([1, 2, 49, -11], key=abs)) # 按照绝对值从小到大进行排序
  4.  
  5. print(sorted(['abs', 'Ab', 'ZO'])) # 这个sorted对字符串进行排序的时候是根据首字符的ASCII进行排序的
  6. print(sorted(['abs', 'Ab', 'ZO'], key=str.lower)) # 这个表示按照字符串首字母进行排序,但是这里的话我们忽略大小写

5. 返回函数

一个函数的返回值不仅仅是一个数,也还可以是一个函数,这样的高阶函数称为返回函数

  1. def laze_sum(*args):
  2. def sum_up(): # 这个是通过可变参数进行求和运算的
  3. sumnum = 0
  4. for n in args:
  5. sumnum = sumnum + n
  6. return sumnum
  7. return sum_up
  8.  
  9. f1 = laze_sum(1, 2, 3)
  10. f2 = laze_sum(1, 2, 3)
  11. print(f1) # <function laze_sum.<locals>.sum_up at 0x0000023C5DED3D90>输出这样一个数
  12. if f1 == f2:
  13. print('True')
  14. else:
  15. print('no')

6. 匿名函数

在Python中有时候我们不需要显示的调用函数,或者说我们仅仅想要产生一个可以作用的函数,这时候我们就可以使用匿名函数了,这样我们就可以匿名函数输出简单的函数,而不需要用户自己在定义其他函数了,简化了代码,使用lambda关键字:lambda紧跟着的是函数的形参,然后是冒号:,最后是输出变量

  1. print(list(map(lambda x: x*x, [1, 2, 3, 4, 5])))
  2. print(list(map(lambda x: x*x*x, [1, 2, 3, 4, 5]))) # 使用lambda是不会发生重名的错误的

python基础知识16---函数补充的更多相关文章

  1. python基础之内置函数补充、匿名函数、递归函数

    内置函数补充 python divmod()函数:把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b) 语法: 1 divmod(a, b) #a.b为数字,a为除数 ...

  2. python基础知识6——函数

    函数:自定义函数:函数的参数:不带参数,普通参数,默认参数,动态参数:返回值return:函数作用域:内置函数高阶函数:map,reduce,filter,sorted:lambda表达式:文件操作: ...

  3. Python菜鸟之路:Python基础-内置函数补充

    常用内置函数及用法: 1. callable() def callable(i_e_, some_kind_of_function): # real signature unknown; restor ...

  4. Python基础知识:函数

    1.定义函数和调用函数 #定义函数def def greet_user(username): '''简单的问候语''' print('Hello,%s!'%username) greet_user(' ...

  5. python基础知识(七)---数据类型补充、"雷区"、编码

    数据类型补充."雷区".编码 1.数据类型补充 str: #字符串数据类型补充 s1=str(123) #常用于类型转换 print(s1) #capitalize()首字母大写 ...

  6. 深入理解python(四)python基础知识之函数

    函数部分 函数部分大概想分成两个部分来讲,第一部分是关于对函数参数的介绍,第二部分是局部变量全局变量和内置变量也就是变量作用域的LGB原则 函数的参数 1.关于形参和实参的问题 第一点要注意的是pyt ...

  7. python基础知识(函数2)

    返回值 return return[value]  多个值用,逗号分开,没有返回值,会返回none值,函数不给指定返回值也会返回none值 def functionname(p1,p2,p3): re ...

  8. python基础知识(函数)

    创建函数 def 函数名(可以选参数): 可选参数  '''  ''' 用三引号括起来的注释  说明功能和参数信息 可选参数指定函数体  执行函数程序代码 创建一个空函数 def empty(): p ...

  9. Python基础知识总结笔记(四)函数

    Python基础知识总结笔记(四)函数python中的函数函数中的参数变量作用域偏函数PFA递归函数高阶函数BIFs中的高阶函数匿名函数lambda闭包Closure装饰器Decorator函数式编程 ...

随机推荐

  1. 树莓派外网ssh访问holer实现篇

    外网ssh访问树莓派 内网的树莓派(Raspberry Pi),只能在局域网内访问,怎样从公网也能ssh登录访问树莓派? 本文将介绍使用holer实现的具体步骤. 1. 准备工作 1.1 安装并启动树 ...

  2. docker学习笔记(3)

    docker 搭建私有仓库 docker-registry是官方提供的工具,可以用于构建私有的镜像仓库.本文内容基于 docker-registry v2.x 版本. 安装运行 docker-regi ...

  3. python day33 ,socketserver多线程传输,ftp作业

    一.一个服务端连多个客户端的方法 1.服务端 import socketserver class MyServer(socketserver.BaseRequestHandler): def hand ...

  4. Docker 部署应用过程记录

    Kibana直接部署到centos中,老是没有任何征兆退出,今天将他移动到docker中部署,以下是部署的过程,做个记录防止忘记 1.安装Docker # yum install docker 2.启 ...

  5. 使用XHProf查找PHP性能瓶颈

    XHProf是facebook 开发的一个测试php性能的扩展,本文记录了在PHP应用中使用XHProf对PHP进行性能优化,查找性能瓶颈的方法. 一.安装Xhprof扩展 //github上下载ht ...

  6. 常用css

    边框 css   基本设置:border:1px solid #d2d2d2;    风格有:solid=>实线 double=>双实线 dotted=>点状 dashed=> ...

  7. VirtualBox安装Archlinux并配置桌面环境

    最近无聊,就找来archlinux来玩一玩,去archlinux wiki上看了一下教程.以下是操作过程. 1. 下载镜像,下载地址; 2. 启动archlinux并选择Boot Arch Linux ...

  8. idea 启动 springBoot debug很慢,正常启动很快是什么原因

    说实话,从我开始使用springboot框架以来,就一直遇到这个问题,我刚把项目从SSM框架转成 spring boot 框架时,就发现有时候启动项目特别慢,有时候特别快,当时觉得特别奇怪,但也一直没 ...

  9. 剑指offer7~10题

    斐波那契数列 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项. n<=39 思路:此题用递归会超内存,故直接循环. 代码: class Solution { pub ...

  10. 18.python关于mysql的api

    一.pymysql模块1.pymysql是Python中操作MySQL的模块2.执行sql语句(1)连接数据库: import pymysql #连接mysql数据库创建conn对象(host连接的机 ...