美文网首页
函数进阶

函数进阶

作者: Vector_Wan | 来源:发表于2019-05-18 22:49 被阅读0次

    主要包括:

    • 星号表达式(starred expression)
    • 快速传入多个参数
    • 变长度参数的传入
    • 多个返回值的情况

    一、快速传入多个参数

    函数在调用多个参数时,在列表、元组、集合、字典及其他可迭代对象作为实参,并在前面加 *后传入

    *(1,2,3)解释器将自动进行解包然后传递给多个单变量参数(参数个数要对应相等)。

    我理解 *可迭代对象 就是将可迭代对象普通对象之间相互转化的运算符

    但是特别注意:表达式不可单独使用!*

    我们先来看几个小李子:

    t = (1,2,3,4)
    print(*t)
    
    t2 = [5,6,7,8]
    print(*t2)
    
    1 2 3 4
    5 6 7 8
    

    所以我们可以多个参数写进一个元组里,然后把这个元组当做相应函数的参数列表传进去:

    def f(a, b, c, d):
        print(a, b, c, d, sep = '&')
        
    f(1,2,3,4)
    f(*(1,2,3,4))
    
    1&2&3&4
    1&2&3&4
    

    传入列表也是可以的:

    *会将列表[1,2,3,4]中的数字取出来,分别赋给参数a,b,c,d

    def f(a, b, c, d):
        print(a, b, c, d, sep = '&')
        
    f(1,2,3,4)
    f(*[1,2,3,4])
    
    1&2&3&4
    1&2&3&4
    

    下面这个函数可以实现与上面一样的功能:

    注意print函数中的 args 前面必须加 * 号

    def f(*args):
        print(*args, sep='&')
        
    f(1,2,3,4)
    f(*(1,2,3))
    
    1&2&3&4
    1&2&3
    

    这个用法有些意思,下面详细介绍一下:

    二、将任意个数的参数导入到python函数中(变长参数的传入)

    出现在函数的参数中的星号表达式 *args 用于将传入的可迭代参数序列解析出来,并存入 args 中。

    • *args 会将传入的变长参数放入名为 args 的元组中
    • **kwargs 会将传入的变长参数放入名为 kwargs 的字典中

    1.使用*args将传入的变长参数放入名为 args 的元组中

    def self_print(*a):
        print(a)
        print(type(a))
        
    self_print(1,2,3,4,5,6)
    
    (1, 2, 3, 4, 5, 6)
    <class 'tuple'>
    
    def self_print(name,*a):
        print(a)
        print(type(a))
        
    self_print(1,2,3,4,5,6)
    
    (2, 3, 4, 5, 6)
    <class 'tuple'>
    

    上面这个用法使用了Python的拆包操作。第一个值赋给 name 剩下的参数存入名字为 a 的元组中。

    下面来看一个实际的应用:用numpy创建一个大小与m相同的随机矩阵:

    由于矩阵 m 的维度不能确定所以采用变长参数传入

    import numpy as np
    np.random.randn(*m.shape)
    

    函数randn接收n个可选参数:numpy.random.randn(d0, d1, …, dn)

    2.使用**kwargs将将传入的参数放入名为 kwargs 的字典中

    • 字典名为 kwargs
    • 字典的键为形参(就这么记吧估计实际上并不是)
    • 字典的值为实参
    def d_self_print(**kwargs):
        print(kwargs)
        print(type(kwargs))
        
    d_self_print(last_name = "Wan", first_name = "Vector")
    
    {'last_name': 'Wan', 'first_name': 'Vector'}
    <class 'dict'>
    

    3. 混合参数的传入

    注意形参的顺序:位置参数->元组->字典

    def mix(name, *t, **kw):
        print(name)
        print(t)
        print(kw)
        
    mix("Vector",20,'NEUQ',) # 当参数为空 注意那个逗号!!!
    print('*'*20)
    mix("Vector",20,'NEUQ',gender = "男")
    
    
    Vector
    (20, 'NEUQ')
    {}
    ********************
    Vector
    (20, 'NEUQ')
    {'gender': '男'}
    
    # 这是一个错误的示范:
    def mix( *t, **kw, name = 'qq'):
        print(name)
        print(t)
        print(kw)
    
      File "<ipython-input-12-d64f7f8770cc>", line 2
        def mix( *t, **kw, name = 'qq'):
                              ^
    SyntaxError: invalid syntax
    
    def mix(name, last_name = 'a', *t, **kw):
        print(name)
        print(last_name)
        print(t)
        print(kw)
        
    mix("Vector",20,'NEUQ',) # 当参数为空
    
    Vector
    20
    ('NEUQ',)
    {}
    

    三、返回多个返回值

    def sum_and_avg (*numbs):
        total = sum(numbs)
        avg_number = total/ len(numbs)
        return total, avg_number
    
    sum_of_num,avg = sum_and_avg(1,2,3,4,5,6,7,8,9,10)
    print('总和是:%f'%sum_of_num)
    print('平均值为:%f'%avg)
    
    总和是:55.000000
    平均值为:5.500000
    

    下面是一些关于星号表达式的补充:

    一、用于 unpack 可迭代的变量

    1.赋值语句中的 * 用于列表数值取出

    a, *b, c = range(5)
    print('a:',a,'\nb:' ,b,'\nc:' ,c)
    
    a: 0 
    b: [1, 2, 3] 
    c: 4
    
    record = ('Vector', 50, 123.45, (5, 18, 2019))
    name, *_1, (*_2, year) = record
    print('name:',name,'\n_1:',_1,'\n_2:',_2,'\nyear:',year)
    
    name: Vector 
    _1: [50, 123.45] 
    _2: [5, 18] 
    year: 2019
    
    for a, *b in [(1, 2, 3), (4, 5, 6, 7)]:
        print(b)
    
    [2, 3]
    [5, 6, 7]
    
    1. 用于递归(列表求和)
    def sum(items):
        head, *tail = items
        return head + sum(tail) if tail else head
    items = [1, 10, 7, 4, 5, 9]
    print(sum(items))
    
    36
    

    注意:表达式不可单独使用!*

    错误用法:

    >>> *a = range(5)
    >>> a = *range(5)
    >>> print(*range(5))
    
    # 正确用法
    *a, = range(5)
    a = *range(5),
    *a,b = range(5)
    print(*range(5),)
    
    0 1 2 3 4
    

    这让我想到了单独一个元素的数组应该写成(a,)

    a = 1
    print(type(a,))
    print(type(a))
    print(type((a,)))
    
    <class 'int'>
    <class 'int'>
    <class 'tuple'>
    

    相关文章

      网友评论

          本文标题:函数进阶

          本文链接:https://www.haomeiwen.com/subject/gbvxzqtx.html