Python函数基础

1. Python中函数的概念

1.1 python中函数概念

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

1.2 python中函数定义方法解释

python中函数定义方法:
 
def test(x):
    "The function definitions"
    x+=1
    return x
     
def:定义函数的关键字
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 函数和过程

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

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

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

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

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

总结:

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

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

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

1.4 Python中函数的好处

    1.代码重用

    2.保持一致性,易维护

    3.可扩展性

2. 局部变量和全局变量

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

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

当全局变量与局部变量同名时:
在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。
name='xyz'

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)

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

def action():
    print 'in the action'
    logger()
action()
报错NameError: global name 'logger' is not defined


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

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

4. 嵌套函数和作用域

举例如下:

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

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

例一:
name='aaa'

def loo():
    name='bbb'
    def car():
        print(name)
    return bar

kkk=loo()
kkk()


例二:
name='aaa'

def loo():
    name='bbb'
    def car():
        name='ccc'
        def hh():
            print(name)
        return hh
    return car

uuu=loo()
uuu()()

5. 递归调用函数

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

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

递归特性:

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

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

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

堆栈扫盲http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html 

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

6. 匿名函数

#正常函数的写法
def test(x):
    y = x**2
    return y
#匿名函数的写法
lamada x:x**2

7. 函数式编程

7.1 高阶函数

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

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

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

7.2 map函数

array=[1,3,4,71,2]

ret=[]
for i in array:
    ret.append(i**2)
print(ret)

#如果我们有一万个列表,那么你只能把上面的逻辑定义成函数
def map_test(array):
    ret=[]
    for i in array:
        ret.append(i**2)
    return ret

print(map_test(array))

#如果我们的需求变了,不是把列表中每个元素都平方,还有加1,减一,那么可以这样
def add_num(x):
    return x+1
def map_test(func,array):
    ret=[]
    for i in array:
        ret.append(func(i))
    return ret

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 in array:
        if func(i):
            ret.append(i)
    return ret

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 import reduce
#合并,得一个合并的结果
array_test=[1,2,3,4,5,6,7]
array=range(100)

#报错啊,res没有指定初始值
def reduce_test(func,array):
    l=list(array)
    for i in l:
        res=func(res,i)
    return res

# print(reduce_test(lambda x,y:x+y,array))

#可以从列表左边弹出第一个值
def reduce_test(func,array):
    l=list(array)
    res=l.pop(0)
    for i in l:
        res=func(res,i)
    return res

print(reduce_test(lambda x,y:x+y,array))

#我们应该支持用户自己传入初始值
def reduce_test(func,array,init=None):
    l=list(array)
    if init is None:
        res=l.pop(0)
    else:
        res=init
    for i in l:
        res=func(res,i)
    return res

print(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过滤掉千年王八,万年龟,还有一个九千岁
def func(x):
    age_list=[1000,10000,9000]
    return x['age'] not in age_list


res=filter(func,name_dic)
for i in res:
    print(i)

res=filter(lambda x:x['age'] == 18,name_dic)
for i in res:
    print(i)


#reduce用来计算1到100的和
from functools import reduce
print(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 in res:
    print(i)

总结
View Code

函数数编程更多请参考:

https://www.cnblogs.com/linhaifeng/articles/6113086.html#_label10

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

8. 内置函数

内置函数详解:https://docs.python.org/zh-cn/3/library/functions.html?highlight=built#ascii

#取绝对值
# 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 = xyz
print(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()


感谢林海峰老师的博客支持,本章引用非常多,再次感谢!
原博地址:https://www.cnblogs.com/linhaifeng/articles/6113086.html#_label10
原文地址:https://www.cnblogs.com/wangzengyi/p/12191252.html