使用函数的优点
可以降低代码量(调用函数只需要一行,而拷贝粘贴需要N倍代码)
可以降低维护成本(函数只需修改def部分内容,而拷贝粘贴则需要每一处出现的地方都作修改)
使程序更容易阅读(没有人想看到一个程序重复N行)
创建函数的语法
def MyFun(x,y):
# 我是函数体
# 我也是函数体
# 我们都属于函数MyFun()
# 噢,我不属于MyFun()函数的了
函数可以有多个参数
几个小例子:
1,关于 return
def hello():
print('Hello World!')
return
print('Welcome To FishC.com!')
会打印:
hello()
Hello World!
#因为当Python执行到 return 语句时, Python 认为函数到此结束,需要返回了,尽管没有任何返回值。
2,欧几里得算法求最大公约数(百度百科有算法流程图)(17讲)
def gcd(x, y):
while y:
t = x % y
x = y
y = t
return x
print(gcd(4, 6))
3,十进制转二进制,使用除二取余,并且像bin()一样返回字符串
def Dec2Bin(dec):
temp = []
result = ''
while dec:
quo = dec % 2
dec = dec // 2
temp.append(quo)
while temp:
result += str(temp.pop())
return result
print(Dec2Bin(62))
函数的参数类型
形参指的是函数创建和定义过程中小括号里的参数,而实参值得是在函数调用过程中传递进去的参数。
- 关键字参数:是指函数在调用的时候,带上参数的名字去指定具体调用的是哪个参数,从而可以不用按照参数的顺序去调用函数。
>>> def SaySome(name, words):
print(name + '->' + words)
>>> SaySome(words='让编程改变世界!', name='小甲鱼')
使用关键字参数可以有效避免因不小心搞乱参数的顺序而引起的bug.
2, 默认参数: 在参数定义的过程中,为形参赋初值,当函数调用的时候,不传递实参的话,则默认使用形参的初始值代替。
def saysome(name='beautiful girl',words='is me!'):
print(name + '->' + words)
saysome()
beautiful girl -> is me!
3, 收集参数(可变参数):不确定输入的参数个数。
def test(*params):
print('参数的长度是:',len(params))
print('第二个参数是:',params[1])
test(1,'小仙女',3,14,5,6,7,8)
参数的长度是:7
第二个参数是:小仙女
实际上是以一个元组的形式打包进去的。
例子:编写一个函数,分别统计出传入字符串参数(可能不止一个参数)的英文字母,空格,数字和其他字符的个数。
def count(*param):
length = len(param)
for i in range(length):
letters = 0
space = 0
digit = 0
others = 0
for each in param[i]:
if each.isalpha():
letters += 1
elif each.isdigit():
digit += 1
elif each == ' ':
space += 1
else:
others += 1
print('第 %d 个字符串共有:英文字母 %d 个,数字 %d 个,空格 %d 个,其他字符 %d 个。' % (i+1, letters, digit, space, others))
count('I love fishc.com.', 'I love you, you love me.')
内嵌函数和闭包
- 如果希望在函数中修改全局变量的值,应该使用什么关键字?–global
>>> count = 5
>>> def MyFun():
global count
count = 10
print(count)
>>> MyFun()
10
>>> count
10
- 在嵌套的函数中,如果希望在内部函数修改外部函数的局部变量,应该使用什么关键字?–nonlocal
>>> def Fun1():
x = 5
def Fun2():
nonlocal x
x *= x
return x
return Fun2()
>>> Fun1()
25
#这是初学者很容易犯的错误,如果不添加Nonlocal的话,Python为了保护变量的作用域,故将Fun1()的x变量屏蔽起来,无法访问到外层x的值。
下面看看两个近似的题:
分别是如何访问funIn()呢?
第一个:
def funOut():
def funIn():
print('宾果!你成功访问到我啦!')
return **funIn()**
solution:直接调用funOUT()即可!
funOut()
宾果!你成功访问到我啦!
第二个:
def funOut():
def funIn():
print('宾果!你成功访问到我啦!')
return **funIn**
区别于上一题需要调用 funOut()()访问啦!
funOut()()
宾果!你成功访问到我啦!
或者
go = funOut()
go()
宾果!你成功访问到我啦!
匿名函数:lambda表达式
- lambda x : 2*x+1
说明:x 表示的是函数的参数,冒号后面表示的是函数语句。可以有多个参数。
例子
def fun_A(x, y=3):
return x * y
转换为lambda表达式:
lambda x, y=3 : x * y
下面介绍两个牛逼的BIF filter() 和 map()
filter()
语法:filter(function or None, iterable)
说明:若第一项为None,那么返回 iterable 里为 True 的项。
filter(None,[1,0,False,True])
(直接返回的是object一个对象,在前面加上list即可)
返回 [1.True]
相当于是把任何非 True 的内容给过滤掉。若None->Function,这个函数就是我们可以自己定义的过滤的方法。
比如找出奇数
def odd(x):
return x % 2
temp = range(10)
show = filter(odd,temp)
#前面只要写函数名就可以,不用加括号
list(show)
[1,3,5,7,9]
可以转化为一行实现:
list(filter(lambda x : x % 2, range(10)))
map()
语法:map(function, iterable)。
功能:将序列的每一个元素作为函数的参数进行运算加工,直到可迭代序列的每个元素都加工完毕,返回加工后的元素构成的新序列。
list(map(lambda x : x * 2, range(10)))
[0,2,4,6,8,10,12,14,16,18]
举个用zip()的例子,还记得zip嘛,使用zip会将两数以元组的形式绑定在一块,例如:
>>> list(zip([1, 3, 5, 7, 9], [2, 4, 6, 8, 10]))
[(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
但我们希望打包的形式是灵活多变的列表而不是元组,可以做到吗?使用 map 和 lambda 表达式
>>> list(map(lambda x, y : [x, y], [1, 3, 5, 7, 9], [2, 4, 6, 8, 10]))
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
#强大的map后面是可以接受多个序列作为参数的。