Python-函数
2018-06-18 01:57:59来源:未知 阅读 ()
一、函数作用:
函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
函数式编程最重要的是增强代码的重用性和可读性
二、函数的定义和使用
定义:
1 def 函数名(参数): 2 函数体 3 ..... 4 返回值
-注-
def:定义函数的关键字
返回值后可以跟多个值,最终以元组方式输出
函数的参数:形参、实参
形参被调用时才会分配内存空间
return 执行后,后面的不在执行,且只能有一个return
Python中所谓的过程就是没有返回值的函数
参数:
# Python中有三种参数:普通参数、默认参数,动态参数(针对形参说) # 普通参数 # 此外对参数的理解如下: def test(x,y,z):# 三个都是普通参数 print(x) print(y) print(z) test(1,2,3)# 实参叫位置参数,赋值时 必须一一对应 不能多,也不能少 test(y=1,x=2,z=3) # 关键字参数,不需要一一对应,不能多,也不能少 test(1,2,z=3) # 位置参数必需放在关键字参数左侧,不能多,也不能少 test(1,2,y=3) # 报错,已经对y赋值,在赋值报错 # 默认参数 def handle(x,type='mysql'): print(x) print(type) handle('hello') handle('hello',type='sqlite') handle('hello','sqlite') # 动态参数(也可以叫参数组) def test(x,*args): print(x) print(args) ####### * 与列表有关 ** 与字典有关 ####### *args def test(x,*args): print(x) print(args) test(1) # 1 # () test(1,2,3,4,5) # 1 # (2, 3, 4, 5) test(1,{'name':'alex'}) # 1 # ({'name': 'alex'},) test(1,['x','y','z']) # 1 # (['x', 'y', 'z'],) test(1,*['x','y','z']) # 1 # ('x', 'y', 'z') test(1,*('x','y','z')) # 1 # ('x', 'y', 'z') def test(x,*args): print(x) print(args) # 获得元组 通过for遍历传递 print(args[0]) print(args[0][0]) # test(1) # test(1,2,3,4,5) # test(1,{'1':1}) test(1,['s','a','dd']) # test(1,*['s','a','dd']) ####### **args def test(x,**kwargs): print(x) print(kwargs) test(1,y=2,z=3) test(1,1,2,2,2,2,2,y=2,z=3) # 报错 test(1,y=2,z=3,z=3)#会报错 :一个参数不能传两个值 ######## 混合 def test(x,*args,**kwargs): print(x) print(args,args[-1]) print(kwargs,kwargs.get('y')) # test(1,1,2,1,1,11,1,x=1,y=2,z=3) #报错 x # test(1,1,2,1,1,11,1,y=2,z=3) test(1,*[1,2,3],**{'y':1}) test(1,*[1,2,3],**{'y':1,'z':2})
函数变量:
分为:全局变量、局部变量
1 # 如果函数的内容无global关键字, 2 # - 有声明局部变量 3 # NAME = ["产品经理","廖波湿"] 4 # def qupengfei(): 5 # NAME = "自己" 6 # print('我要搞', NAME) 7 # qupengfei() 8 # - 无声明局部变量 9 # NAME = ["产品经理","廖波湿"] 10 # def qupengfei(): 11 # NAME.append('XXOO') 12 # print('我要搞', NAME) 13 # qupengfei() 14 15 # 如果函数的内容有global关键字 16 # - 有声明局部变量 17 # NAME = ["产品经理","廖波湿"] 18 # def qupengfei(): 19 # global NAME 20 # NAME = "自己" 21 # print('我要搞', NAME) 22 # qupengfei() 23 # 错误示例 24 # NAME = ["产品经理","廖波湿"] 25 # def qupengfei(): 26 # NAME = "自己" 27 # global NAME 28 # print('我要搞', NAME) 29 # qupengfei() 30 # - 无声明局部变量 31 # NAME = ["产品经理","廖波湿"] 32 # def qupengfei(): 33 # global NAME 34 # NAME = ["阿毛"] 35 # NAME.append('XXOO') 36 # print('我要搞', NAME) 37 # qupengfei() 38 39 ######## 全局变量变量名大写 40 ######## 局部变量变量名小写 41 42 43 # 优先读取局部变量,能读取全局变量,无法对全局变量重新赋值 NAME=“fff”, 44 # 但是对于可变类型,可以对内部元素进行操作 45 # 如果函数中有global关键字,变量本质上就是全局的那个变量,可读取可赋值 NAME=“fff”
1 NAME = ["产品经理","廖波湿"] 2 3 def yangjian(): 4 # NAME = "史正文" 5 global NAME # 已经声明,NAME就是全局的的那个变量 6 print('我要搞', NAME) 7 NAME = "小东北" # 修改 全局的变量 8 print('我要搞', NAME) 9 yangjian() 10 11 12 13 14 #### nonlocal,指定上一级变量,如果没有就继续往上直到找到为止 15 16 17 18 name = "刚娘" 19 20 def weihou(): 21 name = "陈卓" 22 def weiweihou(): 23 nonlocal name # nonlocal,指定上一级变量,如果没有就继续往上直到找到为止 24 name = "冷静" 25 26 weiweihou() 27 print(name) 28 29 print(name) 30 weihou() 31 print(name) 32 刚娘 33 冷静 34 刚娘
前向引用
1 ## Python 是先编译后运行 2 def bar(): 3 print('from bar') 4 def foo(): 5 print('from foo') 6 bar() 7 8 foo() 9 10 11 12 def foo(): 13 print('from foo') 14 bar() 15 16 def bar(): 17 print('from bar') 18 foo() 19 20 21 22 报错:不能先调用,后定义 23 def foo(): 24 print('from foo') 25 bar() 26 27 foo() 28 29 def bar(): 30 print('from bar')
递归:
1 递归问路: 2 3 import time 4 5 person_list=['alex','wupeiqi','linhaifeng','zsc'] 6 def ask_way(person_list): 7 print('-'*60) 8 if len(person_list) == 0: 9 return '根本没人知道' 10 person=person_list.pop(0) 11 if person == 'linhaifeng': 12 return '%s说:我知道,老男孩就在沙河汇德商厦,下地铁就是' %person 13 14 print('hi 美男[%s],敢问路在何方' % person) 15 print('%s回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问%s...' % (person, person_list)) 16 time.sleep(1) 17 res=ask_way(person_list) 18 19 20 print('%s问的结果是: %res' %(person,res)) 21 return res 22 23 res=ask_way(person_list) 24 print(res)
递归特性:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,
每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,
所以,递归调用的次数过多,会导致栈溢出)
1 data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35] 2 3 4 def binary_search(dataset, find_num): 5 print(dataset) 6 7 if len(dataset) > 1: 8 mid = int(len(dataset) / 2) 9 if dataset[mid] == find_num: # find it 10 print("找到数字", dataset[mid]) 11 elif dataset[mid] > find_num: # 找的数在mid左面 12 print("\033[31;1m找的数在mid[%s]左面\033[0m" % dataset[mid]) 13 return binary_search(dataset[0:mid], find_num) 14 else: # 找的数在mid右面 15 print("\033[32;1m找的数在mid[%s]右面\033[0m" % dataset[mid]) 16 return binary_search(dataset[mid + 1:], find_num) 17 else: 18 if dataset[0] == find_num: # find it 19 print("找到数字啦", dataset[0]) 20 else: 21 print("没的分了,要找的数字[%s]不在列表里" % find_num) 22 23 24 binary_search(data, 66) 25 26 27 28 29 ##### 结果 30 [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35] 31 找的数在mid[18]右面 32 [20, 21, 22, 23, 30, 32, 33, 35] 33 找的数在mid[30]右面 34 [32, 33, 35] 35 找的数在mid[33]右面 36 [35] 37 没的分了,要找的数字[66]不在列表里
作用域:
函数的作用域只跟函数声明时定义的作用域有关,跟函数的调用位置无任何关系
1 name = 'jack' 2 3 def foo(): 4 name = 'jerry' 5 def bar(): 6 name = 'lucy' 7 print(name) 8 def tt(): 9 print(name) 10 return tt 11 return bar 12 13 func = foo() # 得到的是bar()函数的内存地址 14 func()() # 执行bar() 函数 15 # 可以直接foo()()()
匿名函数:
匿名函数就是不需要显示的指定函数名。模式:lambda x:x+1
1 如下代码: 2 def calc(x): 3 return x+1 4 calc(10) 5 6 用匿名函数表示: 7 func = lambda x:x+1 8 print(func(10)) 9 10 11 12 def test(x,y,z): 13 return x+1,y+1 #----->(x+1,y+1) 14 15 匿名函数表示: 16 lambda x,y,z:(x+1,y+1,z+1)
匿名函数主要用于和其他函数的搭配:
1 l=[3,2,100,999,213,1111,31121,333] 2 print(max(l)) 3 4 dic={'k1':10,'k2':100,'k3':30} 5 6 7 print(max(dic)) 8 print(dic[max(dic,key=lambda k:dic[k])])
1 res = map(lambda x:x**2,[1,5,7,4,8]) 2 for i in res: 3 print(i) 4 5 输出 6 1 7 25 8 49 9 16 10 64
函数式编程:
编程方法论:面向过程、面向对象、函数式
面向过程:简单的说就是没有返回值,一层一层的往下传递,直到实现需求
面向对象:把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为
举例五子棋:
面向过程:1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,8、返回步骤2,9、输出最后结果。
面向对象:1、黑白双方,这两方的行为是一模一样的,2、棋盘系统,负责绘制画面,3、规则系统,负责判定诸如犯规、输赢等。
什么是函数式编程:函数式=编程语言定义的函数 + 数学意义的函数
通俗来讲,函数式就是利用编程语言实现数学函数,这种函数内对象是永恒不变的,要么返回值是函数,要么参数是函数,
没有for和while循环,所有的循环都用递归实现,没有变量赋值,即不改变。但是可读性低,很精简。
1 一、不可变:没有变量,也就没有赋值和修改 2 # 非函数式: 3 a=1 4 def foo(): 5 global a # 尽量啥用 6 a = 2 7 return a 8 foo() 9 print a 10 11 # 函数式 12 a = 1 13 def foo(): 14 return a+1 15 foo() 16 print a 17 18 ###高阶函数 1、函数接收的参数是一个函数名 2、返回值中包含函数 19 ###满足之一就是高阶函数 20 21 二、函数即变量,把函数当做参数传递给另一个函数 22 def foo(n): #n=bar 23 print(n) 24 25 def bar(name): 26 print('my name is %s' %name) 27 28 foo(bar) 29 foo(bar()) #报错 30 foo(bar('alex')) 31 32 33 三、返回值中包含函数 34 def bar(): 35 print('from bar') 36 def foo(): 37 print('from foo') 38 return bar 39 n=foo() 40 n() 41 42 43 def hanle(): 44 print('from handle') 45 return hanle 46 h=hanle() 47 h() 48 49 50 51 def test1(): 52 print('from test1') 53 def test2(): 54 print('from handle') 55 return test1()
1 四、尾调用:在函数的最后一步调用另一个函数(最后一行不一定是函数的最后一步) 2 # 函数bar在foo内是尾调用 3 def bar(n): 4 return n 5 def foo(x): 6 return bar(x) 7 8 # 函数bar1和bar2在foo内是尾调用,二者在if判断条件不同的情况下都有可能作为函数的最后一步 9 def bar1(n): 10 return n 11 def bar2(n): 12 return n+1 13 14 def foo(x): 15 if type(x) is str: 16 return bar1() 17 else: 18 return bar2() 19 20 21 # 函数bar在foo内不是尾调用 22 def bar(n): 23 return n 24 def foo(x): 25 y = bar(x) 26 return y 27 28 # 函数bar在foo内不是尾调用 29 def bar(n): 30 return n 31 def foo(x): 32 return bar(x) +1 # 先执行bar(x)完了还要执行+1操作 所以不是最后一步
1 背景:最后一步调用递归,不要不保存上一次的状态,直接进入下一次递归 2 3 非尾递归 4 def foo(seq): 5 if len(seq) == 1: 6 return seq[0] 7 head,*tail=seq 8 return head + foo(tail) #每次都用head保存状态 9 print(foo(range(100))) 10 11 尾递归 12 def cal(l): 13 print(l) 14 if len(l) == 1: 15 return l[0] 16 first,second,*args=1 17 1[0]=first*second 18 l.pop(1) 19 return cal(l)
高阶函数:(map。filter。reduce.....)
1 #高阶函数 1、函数接收的参数是一个函数名 2、返回值中包含函数 2 # 满足其一即可 3 # 把函数当作参数传给另外一个函数 4 # def foo(n): #n=bar 5 # print(n) 6 # 7 # def bar(name): 8 # print('my name is %s' %name) 9 # 10 # foo(bar) 11 # foo(bar()) 12 # foo(bar('alex')) 13 14 #返回值中包含函数 15 # def bar(): 16 # print('from bar') 17 # def foo(): 18 # print('from foo') 19 # return bar 20 # n=foo() 21 # n() 22 23 def hanle(): 24 print('from handle') 25 return hanle 26 h=hanle() 27 h() 28 29 def test1(): 30 print('from test1') 31 def test2(): 32 print('from handle') 33 return test1()
map函数:
map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。
1 num_l = [1, 2, 10, 5, 3, 7] 2 def map_test(func, array): # func=lambda x:x+1 arrary=[1,2,10,5,3,7] 3 ret = [] 4 for i in array: 5 res = func(i) # add_one(i) 6 ret.append(res) 7 return ret 8 print(map_test(lambda x: x + 1, num_l)) 9 10 res = map(lambda x: x + 1, num_l) 11 12 ## 上面就是map函数的功能,map得到的结果是可迭代对象 13 print('内置函数map,处理结果', res) 14 print('内置函数map,处理结果', list(res)) 15 16 结果: 17 [2, 3, 11, 6, 4, 8] 18 内置函数map,处理结果 <map object at 0x002809F0> 19 内置函数map,处理结果 [2, 3, 11, 6, 4, 8] 20 21 22 map后面的参数是一个可迭代对象,执行map时,相当于执行一个for循环 23 24 print(list(map(lambda x:x+'s','12123123'))) 25 #['1s', '2s', '1s', '2s', '3s', '1s', '2s', '3s'] 26 27 print(list(map(lambda x:x+'s',{'a':1,'b':2}))) 28 # ['as', 'bs']
1 num_l = [1, 2, 10, 5, 3, 7] 2 def map_test(func, array): # func=lambda x:x+1 arrary=[1,2,10,5,3,7] 3 ret = [] 4 for i in array: 5 res = func(i) # add_one(i) 6 ret.append(res) 7 return ret 8 print(map_test(lambda x: x + 1, num_l)) 9 10 res = map(lambda x: x + 1, num_l) 11 12 ## 上面就是map函数的功能,map得到的结果是可迭代对象 13 print('内置函数map,处理结果', res) 14 print('内置函数map,处理结果', list(res)) 15 16 结果: 17 [2, 3, 11, 6, 4, 8] 18 内置函数map,处理结果 <map object at 0x002809F0> 19 内置函数map,处理结果 [2, 3, 11, 6, 4, 8] 20 21 22 map后面的参数是一个可迭代对象,执行map时,相当于执行一个for循环 23 24 print(list(map(lambda x:x+'s','12123123'))) 25 #['1s', '2s', '1s', '2s', '3s', '1s', '2s', '3s'] 26 27 print(list(map(lambda x:x+'s',{'a':1,'b':2}))) 28 # ['as', 'bs']
-注-:
map()函数不改变原有的 list,而是返回一个新的 list。
利用map()函数,可以把一个 list 转换为另一个 list,只需要传入转换函数。
由于list包含的元素可以是任何类型,因此,map() 不仅仅可以处理只包含数值的 list,事实上它可以处理包含任意类型的 list,只要传入的函数f可以处理这种数据类型。
1 def format_name(s): 2 # s1=s[0:1].upper()+s[1:].lower(); 3 s1 = s.capitalize() 4 return s1; 5 6 print(map(format_name, ['adam', 'LISA', 'barT'])) 7 print(list(map(format_name, ['adam', 'LISA', 'barT'])))
filter函数:
filter()函数是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。
1 movie_people=['alex_sb','wupeiqi_sb','linhaifeng','yuanhao_sb'] 2 # def sb_show(n): 3 # return n.endswith('sb') 4 #--->lambda n:n.endswith('sb') 5 6 def filter_test(func,array): 7 ret=[] 8 for p in array: 9 if not func(p): 10 ret.append(p) 11 return ret 12 13 res=filter_test(lambda n:n.endswith('sb'),movie_people) 14 print(res) 15 16 #filter函数 17 movie_people=['alex_sb','wupeiqi_sb','linhaifeng','yuanhao_sb'] 18 print(filter(lambda n:not n.endswith('sb'),movie_people)) 19 #<filter object at 0x01CFC850> 20 print(list(filter(lambda n:not n.endswith('sb'),movie_people))) 21 #['linhaifeng']
-注-:
filter()函数对list中的每一个元素带入f函数进行运算,保留返回结构为真的元素。
reduce函数:
reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。
1 num_l=[1,2,3,100] 2 def reduce_test(func,array,init=None): 3 if init is None: 4 res=array.pop(0) 5 else: 6 res=init 7 for num in array: 8 res=func(res,num) 9 return res 10 11 print(reduce_test(lambda x,y:x*y,num_l,100)) 12 13 14 #reduce函数 15 # 使用reduce()函数先导入模块 16 from functools import reduce 17 num_l=[1,2,3,100] 18 print(reduce(lambda x,y:x+y,num_l,1)) #可以定义起始值,否则默认起始值为第一个元素 19 print(reduce(lambda x,y:x+y,num_l))
小结:
1 #map()处理序列中的每个元素,得到的结果是一个‘列表’,该‘列表’元素个数及位置与原来一样 2 # 3 4 #filter遍历序列中的每个元素,判断每个元素得到布尔值,如果是True则留下来 5 6 people=[ 7 {'name':'alex','age':1000}, 8 {'name':'wupei','age':10000}, 9 {'name':'yuanhao','age':9000}, 10 {'name':'linhaifeng','age':18}, 11 ] 12 print(list(filter(lambda p:p['age']<=18,people))) 13 14 15 #reduce:处理一个序列,然后把序列进行合并操作 16 from functools import reduce 17 print(reduce(lambda x,y:x+y,range(100),100)) 18 print(reduce(lambda x,y:x+y,range(1,101)))
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
下一篇:Pycharm快捷键
- fetchone函数和fetchall函数返回值的区别 2019-08-13
- Python之装饰器笔记 2019-08-13
- Python学习日记(九) 装饰器函数 2019-08-13
- python之函数、面向对象 2019-08-13
- python3基础之“函数(2)” 2019-08-13
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash