python和函数的故事(缺省参数,匿名函数)

缺省参数
python为了简化函数的调用,提供了默认的参数机制

制作一个函数,名为pow,传入默认形参n=2,计算任意一个数的平方

def pow(x, n = 2):      #定义一个函数pow,传入形参x,设置形参n=2,如果实参中没有指定的话,那么参数n就是用默认值2带入式中
    r = 1                
    while n > 0:              
        r *= x        #即就是r=r*x
        n -= 1
    return r
pow(5)              #将实参5传递给形参x,没有传第二个实参得值,那么形参n默认为为2
print(pow(5))       #输出函数的值为25

在定义有默认参数的函数时,需要注意以下:

1,必选参数必须在前面,默认参数在后;
2,设置何种参数为默认参数?一般来说,将参数值变化小的设置为默认参数。

在python的内置函数中也存在着默认参数:

print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

2.不定长参数

有时可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数(或者可变参数,不定的意思就是不确定函数使用者会传递多少个参数给形参,不定长参数包括*args和 **kwargs语法

*args 是可变的位置参数(positional arguments)列表,用来发送一个非键值对的可变数量的参数列表给一个函数
**kwargs 是可变的关键词参数(keyword arguments)列表。
并且规定位置参数必须位于关键词参数之前,即 *args 必须位于 **kwargs 之前。**kwargs用于将不定长度的键值对作为实参值传递给形参。

基本语法如下:

def  函数名(形参,*args):
    函数体
函数名(实参1,实参2.....)

加了星号(*)的变量args会存放所有非键值对的可变数量的参数列表,参数args数据类型为元组;

def num(a,b,*args):   #设置形参a,b和不定长参数*args,其参数args可以自定义名称,一般使用args表示
    print ("a is", a)    
    print ("b is", b)
    print ("args is", args)
num(11,22,33,44,55,66)    #将11传递给形参a,将12传递给形参b,将剩下的实参都传给args参数中组成一个元组

输出结果为:

a is 11
b is 22
args is (33, 44, 55, 66)

而加**的变量kwargs会存放不定长度的键值对作为实参值传递给形参。

def fun(a, b, *args, **kwargs):
    print ("a =", a)
    print ("b =", b)
    print ("args =", args)
    print ("kwargs: ")      
    for key, value in kwargs.items(): #对字典的键值进行遍历
        print (key, "=", value)
fun(1, 2, 3, 4, 5, m=6, n=7, p=8)   #将实参1传递给形参a,实参2传递给形参b,将非键值对的值全部传递给不定长参数args,将键值对的值传递给不定长参数**kwargs

得到的结果为:

a = 1
b = 2
args = (3, 4, 5)
kwargs: 
m = 6
n = 7
p = 8

匿名函数
在Python,有两种函数,一种是def定义的函数,需要设置函数名,一种是lambda函数(一种生成函数对象的表达式形式,不需要设置函数名,因为她和LISP语言很相似,所以取名字为lambda函数)

python 使用 lambda 来创建匿名函数。

所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。

  1. lambda 只是一个表达式,函数体比 def 简单很多。
    1. lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
    2. lambda函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
    3. 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。

其格式为:lambda 形参(可省略):返回值

lambda方法的使用(无参数)

#使用def定义函数的方法
def true():
    return True
#等价的lambda表达式
>>>lambda : True
<function <lambda> at 0x000001EA532869D8>
#保留lambda对象到变量中,以便随时调用
>>>true = lambda :True
>>>true()
True

lambda方法的使用(有参数)

#使用def定义的函数
def add(x,y):
    return x+y
#使用lambda方法的表达式
lambda x,y:x+y

#lambda也允许有默认值和使用可变长参数
lambda x,y=2:x+y
lambda *args:z

#调用lambda函数
>>>a=lambda x,y:x+y
>>>a(1,3)
4
>>>b=lambda x,y=2:x+y
>>>b(1)
3
>>>b(1,3)
4
>>>c=lambda *args:args
>>>c(10,'test')
(10,'test')

使用map()函数将lambda创建的函数作用于一个数据类型的每一个元素中,map函数的原型是map(function, iterable, …),在python3中它的返回结果是一个指针。

参数function传的是一个函数名,可以是python内置的,也可以是自定义的。
参数iterable传的是一个可以迭代的对象,例如列表,元组,字符串这样的。

这个函数的意思就是将function应用于iterable的每一个元素,结果以列表的形式返回。注意到没有,iterable后面还有省略号,意思就是可以传很多个iterable,如果有额外的iterable参数,并行的从这些参数中取元素,并调用function。如果一个iterable参数比另外的iterable参数要短,将以None扩展该参数元素。还是看例子来理解吧!
例如:

list(map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])) 

使用lambda方法创建一个计算平方的函数,使用map函数将所创建的求平方的函数作用于这个列表中,得到的是指针,然后使用list()函数将其转化成列表
得到的值为:

[1, 4, 9, 16, 25, 36, 49, 64, 81]

使用lambda函数对列表中的字典进行排序

infors=[{"name":"laoli","age":40},{"name":"xiaoming","age":20},{"name":"banzhang","age":10}]
infors.sort(key=lambda x:x['name'])  #第一个x表示infors列表中的每个元素,lambda方法所定义的函数表示从列表中的每个元素(字典)中去除主键出来,然后使用sort方法进行排序
print(infors)

得到的结果为:

[{'name': 'banzhang', 'age': 10}, {'name': 'laoli', 'age': 40}, {'name': 'xiaoming', 'age': 20}]

匿名函数作为实参传递给函数

def test(a,b,func):    #设置形参func用来接收实参lambda所创建的函数
    result=func(11,22)       #将11和22传递给func函数
    return result            #将程序值返回
num=test(11,22,lambda x,y:x+y) #将lambda所创建的函数作为实参传递给func
print(num)    

程序首先执行调用函数的那段代码,即执行 test(11,22,lambda x,y:x+y),那么就将11赋值给形参a,12赋值给形参b,lambda所创建的函数赋值给参数func,准确说应该是形参a指向存放数字11的地址才对,,,然后程序执行调用函数那段,对于func(11,22)即就是将11和22赋值给lambda所创建的函数的参数x和y,即x=11,y=12,那么计算的的结果就是result=11+22=33,又将result返回,执行调用函数那段代码,即num=result=33

猜你喜欢

转载自blog.csdn.net/qq_39353923/article/details/82290703