定义函数:
#语法 def 函数名(参数1,参数2,参数3,...): ‘‘‘注释‘‘‘ 函数体 return 返回的值 #函数名要能反映其意义
过程:就是没有返回值的函数
函数的参数:
- 形参:只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。
- 实参:可以是常量、变量、表达式、函数等,在进行函数调用时,都必须有确定的值,以便把这些值传给形参。
def test(x,y,z): #x=1,y=2,z=3 print(x) print(y) print(z) #位置参数,必须一一对应,缺一不行多一也不行 test(1,2,3) #关键字参数,无须一一对应,缺一不行多一也不行 test(y=1,x=2,z=3) #输出结果: 1 2 3 2 1 3
#参数组:**字典 *列表 def test(x,*args,**kwargs): print(x) print(args,args[-1]) print(kwargs,kwargs.get(‘s‘)) test(1,*[1,2,3],**{‘s‘:1}) #输出结果: 1 (1, 2, 3) 3 {‘s‘: 1} 1
全局变量和局部变量:
在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
当全局变量与局部变量同名时:在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。
name=‘reese‘ def change_name(): print(‘我的名字‘,name) change_name() def change_name(): name=‘帅‘ print(‘我的名字‘,name) change_name() print(name) def change_name(): global name name=‘帅‘ print(‘我的名字‘,name) change_name() print(name) #输出结果: 我的名字 reese 我的名字 帅 reese 我的名字 帅 帅
# 如果函数内部无global关键字,优先读取局部变量,能读取全局变量,无法对全局变量重新赋值;
但对于可变类型(除数字、字符串、元祖,其他都可变),可对内部元素进行操作。
# 如果函数内部有global关键字,变量本质上是全局变量,可读取可赋值。
# 一般全局变量名用大写,局部变量名用小写。
递归
#递归调用 def calc(n): print(n) if int(n / 2) == 0: return n s = calc(int(n / 2)) return s calc(10) #输出: 10 5 2 1
递归特性:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,
每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)
#问路 import time person_list=[‘林克‘,‘士官长‘,‘奎爷‘,‘但丁‘] def ask_way(person_list): print(‘-‘*60) if len(person_list) == 0: return ‘没人知道‘ person=person_list.pop(0) if person == ‘但丁‘: return ‘%s说:我知道,路在脚下,走多了,也就知道了‘ %person print(‘hi 美男[%s],敢问路在何方‘ %person) print(‘%s回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问%s...‘ %(person,person_list)) time.sleep(3) res=ask_way(person_list) # print(‘%s问的结果是: %res‘ %(person,res)) return res res=ask_way(person_list) print(res)
函数作用域
作用域在定义函数时就已经固定住了,不会随着调用位置的改变而改变
name = "reese" def s(): name = "neo" def n(): print(name) return n func = s() func() #输出: neo
匿名函数:
不需要显示的指定函数
def calc(x): return x + 10 res = calc(10) print(res) #输出: 20 #用匿名函数: func = lambda x: x + 10 print(func(10)) #输出: 20
func = lambda x, y, z: x + y + z print(func(1, 2, 3)) #输出: 6
map函数:
num = [3, 4, 5, 6, 11, 7, 54] #lambda x:x+1 def add_one(x): #列表元素自增一 return x + 1 #lambda x:x-1 def minus_one(x): #列表元素自减一 return x - 1 def map_test(func, array): ret = [] for i in num: res = func(i) ret.append(res) return ret print(map_test(add_one,num)) # print(map_test(lambda x:x+1,num)) #可用匿名函数 print(map_test(minus_one,num)) # print(map_test(lambda x:x-1,num)) #终极版本 def map_test(func,array): ret = [] for i in array: res = func(i) ret.append(res) return ret print(map_test(lambda x:x+1,num)) #输出结果: [4, 5, 6, 7, 12, 8, 55] [2, 3, 4, 5, 10, 6, 53] [4, 5, 6, 7, 12, 8, 55]
map:
处理序列中的每个元素,得到的结果是一个列表,该列表元素个数及位置与原来一样
num = [3, 4, 5, 6, 11, 7, 54] res=map(lambda x:x+1,num) print(‘内置函数map,处理结果‘,list(res)) print(list(map(minus_one,num))) msg = "reese" print(list(map(lambda x:x.upper(),msg))) #输出结果: 内置函数map,处理结果 [4, 5, 6, 7, 12, 8, 55] [2, 3, 4, 5, 10, 6, 53] [‘R‘, ‘E‘, ‘E‘, ‘S‘, ‘E‘]
filter函数:
便利序列中的每个元素,判断每个元素得到布尔值,如果是True则留下来
people = [‘reese‘, ‘neo_s‘, ‘林克‘] print(filter(lambda n: not n.endswith(‘s‘), people)) res = filter(lambda n: not n.endswith(‘s‘), people) print(list(res)) print(list(filter(lambda n: not n.endswith(‘s‘), people))) #输出: <filter object at 0x04E612B0> [‘reese‘, ‘林克‘] [‘reese‘, ‘林克‘]
reduce函数:
处理一个序列,然后把序列进行合并操作
# reduce函数 from functools import reduce num = [1, 2, 3, 4, 5] print(reduce(lambda x, y: x + y, num, )) #输出: 15