函数与Lambda表达式
一、函数
-
Python 把函数也当成对象,可以从另一个函数中返回出来而去构建高阶函数,比如:
1.参数是函数
2.返回值是函数 -
函数的定义
1.函数以def关键词开头,后接函数名和圆括号()。
2.函数执行的代码以冒号起始,并且缩进。
3.return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回None。
例:
-
函数的调用
def printstring(str):
print(str)
printstring("i want to call this function that i've defined")
#i want to call this function that i've defined
temp=printstring("hi!")
#hi!
print(temp)
#None 说明该函数没有返回值
- 函数文档
def myfunction(name):
"during function definition,'name'is a parameter"释:函数定义过程中 name是形参,表示占据一个参数位置
print("the '{0}' that comes in is the actual parameter ".format(name))释:传递进来的colaj是实参,因为它是具体参数值
myfunction('colaj')
#the 'colaj' that comes in is the actual parameter
函数参数
Python 的函数具有非常灵活多样的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。从简到繁的参数形态如下:
位置参数
默认参数
可变参数
关键字参数
命名关键字参数
参数组合
- 1.位置参数
arg1 - 位置参数 ,这些参数在调用函数 时位置要固定。 - 2.默认参数
<注>
arg2 = v - 默认参数 = 默认值,调用函数时,默认参数的值如果没有传入,则被认为是默认值。
默认参数一定要放在位置参数 后面,不然程序会报错。
def myfun(name,age=19):
print("name:{0},age:{1}".format(name,age))
myfun('colaj')
myfun('colaj',20)
#name:colaj,age:19 释:默认参数age没有传入,默认age为19
#name:colaj,age:20 释:默认参数age传入为20
Python 允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
def myfun(name,age=19):
print("name:{0},age:{1}".format(name,age))
myfun(age=0,name='colaj')
#name:colaj,age:0
- 可变参数
可变参数就是传入的参数个数是可变的,可以是 0, 1, 2 到任意个,是不定长的参数。
<注>
- *args - 可变参数,可以是从零个到任意个,自动组装成元组。
- 加了星号(*)的变量名会存放所有未命名的变量参数。
def myfun(arg1,*args):
print(arg1)
for i in args:
print(i)
myfun('colaj')
#colaj
myfun('haha','hi','colaj')
#haha
#hi
#colaj
- 关键字参数
**kw - 关键字参数,可以是从零个到任意个,自动组装成字典。
def myfun(arg1,*args,**kwargs):
print(arg1)
print(args)
print(kwargs)
myfun('colaj')
#colaj
#()
#{}
myfun('haha','hi','colaj',name='keke',age=4)
#haha
#('hi', 'colaj')
#{'name': 'keke', 'age': 4}
「可变参数」和「关键字参数」的同异总结:
1.可变参数允许传入零个到任意个参数,它们在函数调用时自动组装为一个元组 (tuple)。
2.关键字参数允许传入零个到任意个参数,它们在函数内部自动组装为一个字典 (dict)。
-命名关键字参数
def printinfo(arg1, *, nkw, **kwargs):
print(arg1)
print(nkw)
print(kwargs)
printinfo(70, nkw=10, a=1, b=2)
# 70
# 10
# {'a': 1, 'b': 2}
printinfo(70, 10, a=1, b=2)
# TypeError: printinfo() takes 1 positional argument but 2 were given
释:没有写参数名nwk,因此 10 被当成「位置参数」,而原函数只有 1 个位置函数,现在调用了 2 个,因此程序会报错。
-
参数组合
在 Python 中定义函数,可以用位置参数、默认参数、可变参数、命名关键字参数和关键字参数,这 5 种参数中的 4 个都可以一起使用,但是注意,参数定义的顺序必须是: -
位置参数、默认参数、可变参数和关键字参数。
-
位置参数、默认参数、命名关键字参数和关键字参数。
<注>命名关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。定义命名关键字参数不要忘了写分隔符 *,否则定义的是位置参数。 -
函数的返回值
def addnum(a,b):
return a+b
print(addnum(4,5))
print(addnum((1,2,3),(4,5,6)))
#9
#(1, 2, 3, 4, 5, 6)
def printme(str):
print(str)
temp = printme('hello') # hello
print(temp) # None
print(type(temp)) # <class 'NoneType'>
- 变量作用域
1.Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
2。定义在函数内部的变量拥有局部作用域,该变量称为局部变量。
3.定义在函数外部的变量拥有全局作用域,该变量称为全局变量。
4.局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。
def discounts(price, rate):
final_price = price * rate
return final_price
old_price = float(input('please input the old_price:'))
rate = float(input('please input the discount rate:'))
new_price = discounts(old_price, rate)
print('the discounted price is:%.2f' % new_price)
#please input the old_price:45
#please input the discount rate:0.88
#the discounted price is:39.60
当内部作用域想修改外部作用域的变量时,就要用到global和nonlocal关键字了。
x='hi!'
def myfun():
global x
print(x)
x='halou!'
print(x)
myfun()
#hi!
#halou!
- 内嵌函数
def outer():
print('outer函数在这被调用')
def inner():
print('inner函数在这被调用')
inner() # 该函数只能在outer函数内部被调用
outer()
# outer函数在这被调用
# inner函数在这被调用
- 闭包
1, 是函数式编程的一个重要的语法结构,是一种特殊的内嵌函数。
2 .如果在一个内部函数里对外层非全局作用域的变量进行引用,那么内部函数就被认为是闭包。
3.通过闭包可以访问外层非全局作用域的变量,这个作用域称为 闭包作用域。
def fun_out(x):
def fun_in(y):
return x+y
return fun_in
a=fun_out(2)
print(type(a))
print(a(3))
#<class 'function'>
#5
例:闭包的返回值通常是函数。
def count(num):
counter=[num]
def jia():
counter[0]+=1
def jian():
counter[0]-=1
def get():
return counter[0]
def reset():
counter[0]=num
return jia,jian,get,reset
jia,jian,get,reset=count(1)
jia()
jia()
print(get())#3
jian()
print(get())#2
reset()
print(get())#1
例:如果要修改闭包作用域中的变量则需要 nonlocal 关键字
def outer():
num=8
print(num)
def inner():
nonlocal num
num=88
inner()
print(num)
outer()
#8
#88
- 递归
如果一个函数在内部调用自身本身,这个函数就是递归函数。
例:n! = 1 x 2 x 3 x … x n
方法一:利用循环
算7!
n=1
for i in range(1,8):
n=n*i
print(n)
#5040
方法二:利用递归
def count(n):
if n==1:
return 1
return n*count(n-1)
print(count(7))
#5040
例:斐波那契数列 f(n)=f(n-1)+f(n-2), f(0)=0 f(1)=1
方法一:利用循环
list1=[0,1]
list2=[0,1]
for i in range(2,11):
temp1=list2[0]
temp2=list2[1]
list2[0]=temp2
list2[1]=temp1+temp2
list1.append(list2[1])
print(list1)
#[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
方法二:利用递归函数
def count(n):
if n<=1:
return n
return count(n-1)+count(n-2)
list1=list()
for n in range(11):
list1.append(count(n))
print(list1)
#[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
Lambda 表达式
匿名函数的定义
在 Python 里有两类函数:
第一类:用 def 关键词定义的正规函数
第二类:用 lambda 关键词定义的匿名函数
python 使用 lambda 关键词来创建匿名函数,而非def关键词,它没有函数名,其语法结构如下:
释:
1。lambda - 定义匿名函数的关键词。
2.argument_list - 函数参数,它们可以是位置参数、默认参数、关键字参数,和正规函数里的参数类型一样。
3.:- 冒号,在函数参数和表达式中间要加个冒号。
4.expression - 只是一个表达式,输入函数参数,输出一些值。
<注>
1.expression 中没有 return 语句,因为 lambda 不需要它来返回,表达式本身结果就是返回值。
2.匿名函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
ls=lambda x:x**2
print(ls)
y=[ls(x) for x in range(11)]
print(y)
#<function <lambda> at 0x000002715B363D30>
#[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
count=lambda x1,x2:x1+x2
print(count(1,2))
#3
count=lambda *args:sum(args)
print(count(1,2,3))
#6
-匿名函数的应用
函数式编程 是指代码中每一块都是不可变的,都由纯函数的形式组成。这里的纯函数,是指函数本身相互独立、互不影响,对于相同的输入,总会有相同的输出,没有任何副作用。
例:非函数式编程
def f(x):
for i in range(0, len(x)):
x[i] += 10
return x
x = [1, 2, 3]
f(x)
print(x)
# [11, 12, 13]
例:函数式编程
def f(x):
y = []
for item in x:
y.append(item + 10)
return y
x = [1, 2, 3]
f(x)
print(x)
# [1, 2, 3]
匿名函数 常常应用于函数式编程的高阶函数中,主要有两种形式:
参数是函数 (filter, map)
返回值是函数 (closure)
例:在 filter和map函数中的应用:
filter(function, iterable) 过滤序列,过滤掉不符合条件的元素,返回一个迭代器对象,如果要转换为列表,可以使用 list() 来转换。
condition=lambda x:x%2==1
lst1=filter(condition,[1,2,3,4,5,6,7,8,9])
print(lst1)
print(list(lst1))
#<filter object at 0x000001DF47A18BE0>
#[1, 3, 5, 7, 9]
*map(function, iterables) 根据提供的函数对指定序列做映射。
m=lambda x:x**2
map1=map(m,[1,2,3,4,5])
print(list(map1))
#[1, 4, 9, 16, 25]
除了 Python 这些内置函数,我们也可以自己定义高阶函数。
def apply_to_list(fun, some_list):
return fun(some_list)
lst = [1, 2, 3, 4, 5]
print(apply_to_list(sum, lst))
# 15
print(apply_to_list(len, lst))
# 5
print(apply_to_list(lambda x: sum(x) / len(x), lst))
# 3.0