Day 06 函数


    1.函数是组织好的,可重复使用的,用来实现单一或相关联动功能的代码段

    2.语法:

        def 函数名(参数列表):

            函数体

            return XXX;  #return返回值,可有可没有,想是啥就是啥,自己定义

        例:

            def add(a,b):

                print(a+b)          #一般不让函数内部执行结果

            add(3,3);                #调用函数并传实参        >>>    6

            ret=add(3,3)          #给add函数传实参并把函数add的返回值赋给ret变量

            print(ret)                >>>none  6            #函数add没有返回值所以输出结果为none

    3.数据类型:可变类型和不可变类型

        1)不可变类型:变量赋值a=5后在赋值a=10,这里实际是新生成一个int值对象10,再让a指向它,而5被丢弃,不是改变5的值,相当于新生成了a。

            python函数中的不可变类型的参数传递实际上是值传递(复制副本),如:整数、字符串、元组。如:fun(a),传递的只是a的值,没有影响a对象本身。比如:在fun(a)内部修改a的值,只是修改另一个复制的对象,不会影响a本身。

        例:

            def fun(a):

                a="李四"

                print("函数内部:",a)                      >>>函数内部:李四

            a="张三"

            print("调用前",a)                                >>>调用前:张三

            fun(a)                #调用函数                >>>函数内部:李四

            print("调用后",a)                                >>>调用后:张三

        2)可变类型:变量赋值la=[1,2,3,4]后在赋值la[2]=5,则是将list la的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。

            python函数中的可变类型的参数传递实际上也是值传递(复制副本),只不过传递的数据类型是可变类型,如:列表,字典。如:fun(la),则是将la真正传递过去,修改后fun外部的la也会受到影响。

                def fun(nums):

                    nums[0]="张飞"

                    nums[1]="刘备"

                nums=["燕青","吴用"]

                print("调用前:",nums)        >>>["燕青","吴用"]

                fun(nums)

                print("调用后:",nums)        >>>["张飞","刘备"]

        3)引用传递:在函数内部修改,将影响函数的值。用值传递的传递方式(复制内存地址的副本)去传递,可变类型可改变内容,不可改变原地址。

                ff={"悟空","八戒"}

                def fun(nums):

                    nums=ff;

                nums=["李逵","武松"]

                print("调用前:",nums)                >>>["李逵","武松"]

                fun(nums)

                print("调用后:",nums)                >>>["李逵","武松"]

    4.函数的正式参数类型:必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这五种参数都可以组合使用,除了可变参数无法和命名关键字混合,但是请注意参数定义的顺序必须是必选参数、默认参数、可变参数、命名关键字参数、关键字参数。

        1)必选参数

            形参和实参一一对应(个数,数据类型,顺序)

            形参:定义方法时的参数

            实参:调用方法时的参数

            def fun1(a,b):

                '''        #  '''  '''在函数第一行为文档内容

                :param a:第一个加数

                :param b:第二个加数

                return:a+b的和

                '''

            h=fun1(3,4)

            print(h)                        >>>7

            print(fun1.__doc__)        #输出文档注释

        2)默认参数(缺省参数):必须写在后面,可以指定参数名,但顺序要保证,否则要指定参数名。

            def fun1(a=3,b=2):

                return a+b;

            h=fun1();            #实参有一个时给形参a,实参有两个时则按顺序给形参a和b

            print(h);            >>>5


            def printinfo(name,age=35):

                print("名字:",name)

                print("年龄:",age)

                return;

            printinfo('ok')                >>>名字:ok

                                                        年龄:35

        3)命名关键字参数

            1.一旦以name=value的传参数的形式存在,以后都要以这种形式存在

            2.name=value的传参数的形式,不要求顺序

            3.('ok',sorce=30,age=30),后者不能重复以name=value赋值

            def show(name,age,sorce=90):

                print('姓名:{} 年龄:{} 成绩:{}'.format(name,age,sorce))

            #普通的实参直接给值,要求顺序、数据类型、个数一一对应            

            show(30,'ok')            #形同不会报错但逻辑是错误的    >>>姓名:30  年龄:ok  成绩:90

            show(sorce=80,age=30,name="ok")        #这种逻辑可以不按顺序

            show('ok',name='ko',age=30)                #会报错,第一个实参默认为name的值与name='ok'相冲突

        4)关键字参数(**kw):关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装成为一个dict(字典)。

            def student(name,age,**kw):

                print('姓名:{} 年龄:{} other:{}'.format(name,age,kw))

            student('tom',30,hao='篮球',ai='足球')        >>>姓名:tom 年龄:30 other:{hao:篮球,ai:足球}

            dic={"一":123,"二"223:,"三":333}

            student('ok',30,**dic)            >>>姓名:ok  年龄:30  other:{"一":123,"二":223,"三":333}

            注:**kw只拷贝原内容,不会影响到函数外的内容

        5)可变参数(不定长参数):可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple(元组)。

            def GetSum(*nums):

                sum=0;

                for i in nums:

                    sum+=i;

                return sum;

            print(GetSum());            >>>0

            print(GetSum(2,3,4,5))        >>>14            # *号位置在形参时,可以接受多个值

            

            t=[2,3,4,5]

            print(GetSum(t))        >>>报错

            print(GetSum(*t))        >>>14                    # *号位置在实参时,可以把元组中的每一个元素拿出来单独使用

        6)组合参数

            def f1(a,b,c=0,*args,**kw):

                print('a=',a,'b=',b,'c=',c,'args=',args,'kw=',kw)

            args=(1,2,3,4)

            kw={'d':99,'x':'#'}

            f1('A','B')                                  >>>a=A  b=B  c=0  args=()  kw={}

            f1(b='B',a='A')                          >>>a=A  b=B  c=0  args=()  kw={}

            f1(b='B',a='A',c=9)                   >>>a=A  b=B  c=9  args=()  kw={}

            f1(args)                                    >>>报错,因为把元组args当成一个值给了a,形参b没有值,所以报错

            f1(*args)                                   >>>a=1  b=2  c=3  args=(4,)  kw={} 

            f1(**kw)                                    >>>报错,没有形参a,b对应的实参           #**kw只能传给形参带两个**号的

            f1(*args,**kw)                            >>>a=1  b=2  c=3  args=(4,)  kw={'d':99,'x':'#'} 

            注:对于任意函数都可以通过类似func(*args,**kw)的形式调用它

        7)小结

            python的函数具有非常灵活的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。默认参数一定要用不可变对象,否则程序运行时会有逻辑错误。

            1.定义可变参数和**kw关键字参数的语法:

                *args是可变参数,args接收的是一个tuple(元组)

                **kw是关键字参数,kw接收的是一个dict(字典)

            2.传参数

                *args会逐个分割args逐个对应形参列表

                **只能对应形参列表的**kw

    5.变量作用域

        1)因为位置不同导致作用域不同,生命周期不同

            a=10;    #全局变量

            def changgeNum():

                a=5;    #局部变量

                print("函数内部:",a)

            print("调用前",a)        >>>调用前:10

            changeNum()            >>>函数内部:5

            print("调用后",a)        >>>调用后:10

        2)global在函数内部声明一个全局变量

            a=10;    

            def changgeNum():

                global a;

                a=5;    

                print("函数内部:",a)

            print("调用前",a)        >>>调用前:10

            changeNum()            >>>函数内部:5

            print("调用后",a)        >>>调用后:5

        3)当全局变量和局部变量重名时,局部变量优先使用,遵循就近一致原则

            g_a=10;

            def fun1():

                g_a=5;

                print("函数内部:",(g_a+10))

            print("调用前:",g_a)        >>>调用前:10

            fun1();                                >>>函数内部:15        #就近使用变量

            print("调用后:",g_a)        >>>调用后:10

    6.匿名函数

        1)python使用lambda来创建匿名函数

        2)语法:lambda[参数列表]:函数体内部代码

            def fun(a,b):

                return a+b;

            print(fun(2,2))        >>>4

            用lambda表达:

            sum=lambda a,b:a+b;

            print(sum(2,2));        >>>4

        3)委托

            def dfdsfe(a,b):

                return a+b;

            def add(a,b,fun):

                print(fun(a,b))

            add(11,22,dfdsfe);        >>>33

            用lambda表达:

            def add(a,b,fun):

                print(fun(a,b))

            add(11,22,lambda a,b:a+b)        >>>33

        4)lambda内置函数:filter()、map()、reduce()

            1.filter():对于序列中的元素进行筛选,最终获取符合条件的序列

                foo=[2,18,9,22,17,24,8,12,27]

                f=filter(lambda x:x%3==0,foo);

                print(list(f));        >>>[18,9,24,12,27]

                #用filter(),可以完成很多功能,例如:删除Nome或空字符串

                def is_not_empty(s):

                    return s and len(s.strip())>0;

                names=['ko',Nome,'','ok'];

                l=list(filter(lambda s:s and len(s.strip())>0,names))

                print(l);            >>>['ko','ok']

            2.map():函数接收两个参数,一个是函数,一个是序列,map将序列的每个元素传入函数中执行,并把结果作为新的list返回。

                print(list(map(laambda x:x%2,range(7))))        >>>[0,1,0,1,0,1,0]

            3.reduce():对于序列内所有元素进行累计操作

                在python 3里,reduce()函数已经被从全局名字空间里移除了,它现在被放置在functools模块里。python中的reduce内建函数是一个二元操作函数,它用来将一个数据集合(链表,元组等)中的所有数据进行操作,用传给reduce中的函数func()(注:必须是一个二元操作函数),先对集合中的第一个和第二个数据进行操作,得到的结果在与第三个数据用func()函数运算,最后得到一个结果。

                import _functools        #下划线是书写格式,书写规范,也可以去掉

                li=(1,2,3,4,5,6,7);

                def add(a,b):

                    return a+b;

                total=_functools.reduce(add,li)

                print(total);                >>>28

                用lambda表达:

                import _functools

                li=(1,2,3,4,5,6,7)

                total=_functools.reduce(lambda a,b:a+b,li)

                print(total);                >>>28

                #reduce()还可以接收第三个可选参数,作为计算的初始值。如果把100作为初始值,那么:

                v=reduce(f,[1,3,5,7,9],100)

                f=lambda a,b:a+b

                print(v);        >>>125

                #python内置了求和函数sum(),但没有求积的函数,请利用reduce()来求积;

                li=[2,4,5,7,12]

                j=reduce(lambda a,b:a*b,li)

                print(j);        >>>3360

        5)python中自定义排序函数:sorted( )

            1.python内置的sorted()函数可对list进行排序

                ol=[1,32,13,4,45,16,7]

                #用list内置函数sort()进行排序

                ol.sort();

                print(ol);        >>>[1,4,7,13,16,32,45]

                #用python内置的sorted()函数可对list进行升序

                ul=sorted(ol);

                print(ul);        >>>[1,4,7,13,16,32,45]

                #用python内置的sorted()函数可对list进行降序

                ul=sorted(ol,reverse=True);        #rexerse默认为False,即升序

                print(ul);        >>>[45,32,16,12,7,4,1]

                #sorted()也是一个高阶函数,它可以接收一个比较函数来实现自定义排序,比较函数的定义是:传入两个带比较的元素x,y,如果x应该排在前面,返回-1;如果x应该在y的后面,返回1;如果x和y相等,返回0。

                l=[('Bob',75),('Adam',92),('Bart',66),('lisa',88)]

                sor=sorted(l,Key=lambda s:s[1],reverse=True);

                print(sor);            >>>[('Adam',92),('lisa',88),('Bob',75),('Bart',66)]

                #sorted()也可以对字符串进行排序,字符串按照ASCII大小来比较

                ol=[('Bob',75),('Adam',92),('bart',66),('lisa',88)]

                sor=sorted(l,key=lambda s:s[0],reverse=False)

                print(sor);            >>>[('Adam',92),('Bob',75),('bart',66),('lisa',88)]

                # 通过.lower()方法忽略大小写

                sor=sorted(l,key=lambda s:str(s[0]).lower(),reverse=False)

                print(sor);            >>>[('Adam',92),('bart',66),('Bob',75),('lisa',88)]

            2.sorted()和.sort()的区别

                1).sort()排序方法

                    shus.sort()对原有列表进行排序,改变原来列表的顺序,无返回值

                    print(shus)就是改变后的列表

                2)sorted()排序函数

                    排序时不影响原数据,产生新的排序数据

                    print(sorted(shus))排序后的结果

                    print(shus)还是原结果


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值