1. Python中函数的概念

1.1 python中函数概念

Python中函数是逻辑结构化和过程化的一种编程方法。

1.2 python中函数定义方法解释

python中函数定义方法:deftest(x):"The function definitions"x+=1

returnxdef:定义函数的关键字

test:函数名

():内可定义形参"":文档描述(非必要,但是强烈建议为你的函数添加描述信息)

x+=1:泛指代码块或程序处理逻辑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=3,z=4)
#位置参数必须在关键字参数左边#test(1,y=2,3)#报错#test(1,3,y=2)#报错#test(1,3,z=2)#test(1,3,z=2,y=4)#报错#test(z=2,1,3)#报错
#def handle(x,type='mysql'):#print(x)#print(type)#handle('hello')#handle('hello',type='sqlite')#handle('hello','sqlite')
#def install(func1=False,func2=True,func3=True):#pass
#参数组:**字典 *列表
def test(x,*args):print(x)print(args)#test(1)#test(1,2,3,4,5)#test(1,{'name':'alex'})#test(1,['x','y','z'])#test(1,*['x','y','z'])#test(1,*('x','y','z'))
#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) #报错#test(1,1,2,1,1,11,1,y=2,z=3)
#test(1,*[1,2,3],**{'y':1})

1.3 函数和过程

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

deftest01():
msg='hello girl'
printmsgdeftest02():
msg='hello word'
printmsgreturnmsg
t1=test01()
t2=test02()print 'from test01 return is [%s]' %t1print 'from test02 return is [%s]' %t2

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

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

deftest01():pass
deftest02():return0deftest03():return 0,10,'hello',['aaa','bbbb'],{'ccccc':'bbbb'}
t1=test01()
t2=test02()
t3=test03()print 'from test01 return is [%s]:' %type(t1),t1print 'from test02 return is [%s]:' %type(t2),t2print 'from test03 return is [%s]:' %type(t3),t3

总结:

返回值的数量=0:返回None

返回值的数量=1:返回object

返回值的数量>1:返回tuple

1.4 Python中函数的好处

1.代码重用

2.保持一致性,易维护

3.可扩展性

2. 局部变量和全局变量

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

全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。

当全局变量与局部变量同名时:

在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。

name='xyz'
defchange_name():print('我的名字',name)
change_name()defchange_name():
name='帅'
print('我的名字',name)
change_name()print(name)defchange_name():globalname
name='帅'
print('我的名字',name)
change_name()print(name)

3. 函数即变量(理解函数的一种方法)

defaction():print 'in the action'logger()

action()

报错NameError:global name 'logger' is notdefineddeflogger():print 'in the logger'

defaction():print 'in the action'logger()

action()defaction():print 'in the action'logger()deflogger():print 'in the logger'action()

4. 嵌套函数和作用域

举例如下:

name = "aaaaa"
defchange_name():
name= "aaaaa2"
defchange_name2():
name= "aaaaa3"
print("第3层打印",name)
change_name2()#调用内层函数
print("第2层打印",name)
change_name()print("最外层打印",name)

此时,在最外层调用change_name2()会出现报错;因为作用域在定义函数时就已经固定住了,不会随着调用位置的改变而改变。

例一:

name='aaa'
defloo():
name='bbb'
defcar():print(name)returnbarkkk=loo()
kkk()

例二:

name='aaa'
defloo():
name='bbb'
defcar():
name='ccc'
defhh():print(name)returnhhreturncaruuu=loo()
uuu()()

5. 递归调用函数

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

defcalc(n):print(n)if int(n/2) ==0:returnnreturn calc(int(n/2))
calc(10)
输出:10
5
2
1

递归特性:

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

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

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

堆栈扫盲

尾递归优化:http://egon09.blog.51cto.com/9161406/1842475

6. 匿名函数

#正常函数的写法

def test(x):

y= x**2

returny

#匿名函数的写法

lamada x:x**2

7. 函数式编程

7.1 高阶函数

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

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

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

7.2 map函数

array=[1,3,4,71,2]
ret=[]for i inarray:
ret.append(i**2)
print(ret)
#如果我们有一万个列表,那么你只能把上面的逻辑定义成函数
def map_test(array):
ret=[]for i inarray:
ret.append(i**2)returnret
print(map_test(array))
#如果我们的需求变了,不是把列表中每个元素都平方,还有加1,减一,那么可以这样
def add_num(x):return x+1def map_test(func,array):
ret=[]for i inarray:
ret.append(func(i))returnret
print(map_test(add_num,array))
#可以使用匿名函数
print(map_test(lambda x:x-1,array))
#上面就是map函数的功能,map得到的结果是可迭代对象
print(map(lambda x:x-1,range(5)))
map函数
View Code

7.3 filter函数


#电影院聚集了一群看电影bb的傻逼,让我们找出他们
movie_people=['alex','wupeiqi','yuanhao','sb_alex','sb_wupeiqi','sb_yuanhao']
def tell_sb(x):return x.startswith('sb')
def filter_test(func,array):
ret=[]for i inarray:iffunc(i):
ret.append(i)returnret
print(filter_test(tell_sb,movie_people))
#函数filter,返回可迭代对象
print(filter(lambda x:x.startswith('sb'),movie_people))
filter函数
View Code

7.4 reduce函数

from functools importreduce#合并,得一个合并的结果
array_test=[1,2,3,4,5,6,7]
array=range(100)#报错啊,res没有指定初始值
defreduce_test(func,array):
l=list(array)for i inl:
res=func(res,i)returnres#print(reduce_test(lambda x,y:x+y,array))
#可以从列表左边弹出第一个值
defreduce_test(func,array):
l=list(array)
res=l.pop(0)for i inl:
res=func(res,i)returnresprint(reduce_test(lambda x,y:x+y,array))#我们应该支持用户自己传入初始值
def reduce_test(func,array,init=None):
l=list(array)if init isNone:
res=l.pop(0)else:
res=initfor i inl:
res=func(res,i)returnresprint(reduce_test(lambda x,y:x+y,array))print(reduce_test(lambda x,y:x+y,array,50))
reduce函数
View Code

7.5 总结

#当然了,map,filter,reduce,可以处理所有数据类型
name_dic=[
{'name':'alex','age':1000},
{'name':'wupeiqi','age':10000},
{'name':'yuanhao','age':9000},
{'name':'linhaifeng','age':18},
]#利用filter过滤掉千年王八,万年龟,还有一个九千岁
deffunc(x):
age_list=[1000,10000,9000]return x['age'] not inage_list
res=filter(func,name_dic)for i inres:print(i)
res=filter(lambda x:x['age'] == 18,name_dic)for i inres:print(i)#reduce用来计算1到100的和
from functools importreduceprint(reduce(lambda x,y:x+y,range(100),100))print(reduce(lambda x,y:x+y,range(1,101)))#用map来处理字符串列表啊,把列表中所有人都变成sb,比方alex_sb
name=['alex','wupeiqi','yuanhao']
res=map(lambda x:x+'_sb',name)for i inres:print(i)

总结

View Code

函数数编程更多请参考:

http://egon09.blog.51cto.com/9161406/1842475

8. 内置函数


#取绝对值#print(abs(-1))#print(abs(1))
#检查多个元素的结果是否为true,有一个为false则为false#特殊情况:只有一个空元素时为true#print(all([1,2,'1']))#print(all([1,2,'1','']))#print(all(''))
#检查多个元素的结果是否为true,有一个为True则为True#print(any([0,'']))#print(any([0,'',1]))
#十进制转换为二进制#print(bin(3))
#判断布尔值结果:空,None,0的布尔值为False,其余都为True#print(bool(''))#print(bool(None))#print(bool(0))
#编码解码#name='你好'#print(bytes(name,encoding='utf-8'))#print(bytes(name,encoding='utf-8').decode('utf-8'))#
#print(bytes(name,encoding='gbk'))#print(bytes(name,encoding='gbk').decode('gbk'))#
#print(bytes(name,encoding='ascii'))#ascii不能编码中文
#判断某个变量有哪些具体变量组成#print(dir(dict))
#计算商数和余数,用来判断某个内容需要多少页#print(divmod(10,3))
#提取字符串中的数字结构#dic={'name':'alex'}#dic_str=str(dic)#print(eval(dic_str))
#可hash的数据类型即不可变数据类型,不可hash的数据类型即可变数据类型#print(hash('12sdfdsaf31231dfasdfasdfasdfasdfasdfasfasfdasdf'))
#打印某内置函数的使用帮助#print(help(all))
#进制转换#print(bin(10))#10进制->2进制#print(hex(12))#10进制->16进制#print(oct(12))#10进制->8进制
#查看内存地址
name =xyzprint(id(name))#判断某个内容是否是被判断的类型#print(isinstance(1,int))#print(isinstance('abc',str))#print(isinstance([],list))#print(isinstance({},dict))#print(isinstance({1,2},set))
#显示全局变量详细信息
name='哈哈哈哈哈哈哈哈哈'
#print(globals())#print(__file__)#
#显示局部变量详细信息#def test():#age='111111111111111111111111111111111111111111'## print(globals())#print(locals())#
#test()
#取最大值和最小值#l=[1,3,100,-1,2]#print(max(l))#print(min(l))#
#拉链函数,将元素1和元素2分别对应组成新的元素对#print(list(zip(('a','n','c'),(1,2,3))))#print(list(zip(('a','n','c'),(1,2,3,4))))#print(list(zip(('a','n','c','d'),(1,2,3))))#
#p={'name':'aaaa','age':18,'gender':'none'}#print(list(zip(p.keys(),p.values())))## print(list(p.keys()))## print(list(p.values()))#
#print(list(zip(['a','b'],'12345')))
age_dic={'a_age':18,'w_age':20,'z_age':100,'l_age':30}#print(max(age_dic.values()))#
##默认比较的是字典的key## print(max(age_dic))#
#for item in zip(age_dic.values(),age_dic.keys()):#print(item)#
#print('=======>',list(max(zip(age_dic.values(),age_dic.keys()))))
#l=[#(5,'e'),#(1,'b'),#(3,'a'),#(4,'d'),#]## l1=['a10','b12','c10',100] #不同类型之间不能进行比较#l1=['a10','a2','a10'] #不同类型之间不能进行比较#print(list(max(l)))#print('--->',list(max(l1)))#
#l=[1,3,100,-1,2]#print(max(l))#dic={'age1':18,'age2':10}#print(max(dic)) #比较的是key#print(max(dic.values())) #比较的是values,但不知是哪个key对应的#print(max(zip(dic.values(),dic.keys()))) #结合zip使用#
#MAX终极用法#people=[#{'name':'a','age':1000},#{'name':'w','age':10000},#{'name':'y','age':9000},#{'name':'l','age':18},#]#print(max(people,key=lambda dic:dic['age']))
#MAX的用法类似于这个原理:#ret=[]#for item in people:#ret.append(item['age'])#print(ret)#max(ret)
#关于ASCII码,chr通过索引找字符,ord通过字符找索引#print(chr(97))#print(ord('a'))
#print(pow(3,3)) #3**3#print(pow(3,3,2)) #3**3%2
#按照相反的顺序排序#l=[1,2,3,4]#print(list(reversed(l)))#print(l)
#四舍五入#print(round(3.5))
#设置集合#print(set('hello'))
#设置切片取值的范围和步长#l='hello'#s1=slice(3,5)#s2=slice(1,4,2)## print(l[3:5])#print(l[s1])#print(l[s2])#print(s2.start)#print(s2.stop)#print(s2.step)
#sorted按照从小到大进行排序#l=[3,2,1,5,7]#l1=[3,2,'a',1,5,7]#print(sorted(l))## print(sorted(l1)) #排序本质就是在比较大小,不同类型之间不可以比较大小#people=[#{'name':'a','age':1000},#{'name':'w','age':10000},#{'name':'y','age':9000},#{'name':'l','age':18},#]#print(sorted(people,key=lambda dic:dic['age']))#name_dic={#'ab': 11900,#'al':1200,#'wu':300,#}#print(sorted(name_dic))#
#print(sorted(name_dic,key=lambda key:name_dic[key]))#
#print(sorted(zip(name_dic.values(),name_dic.keys())))
#type查看数据类型#print(str('1'))#print(type(str({'a':1})))#dic_str=str({'a':1})#print(type(eval(dic_str)))
#sum求和#l=[1,2,3,4]#print(sum(l))#print(sum(range(5)))#
#
#print(type(1))#
#msg='123'#
#if type(msg) is str:#msg=int(msg)#res=msg+1#print(res)#
#VAR不带参数和locals一样,带一个参数是以字典的形式显示该参数的功能#def test():#msg='未来日记勒韦尔'#print(locals())#print(vars())#test()#print(vars(int))
#import是引入模块的函数#import------>sys----->__import__()#import test#test.say_hi()
#如果要引入字符串类型的模块,就需要_import_引入#import 'test'#报错
# module_name='test'# m=__import__(module_name)
# m.say_hi()