• Python初学者必须了解的星号(*)90%的人都不懂


     

    本书各大电商平台有售

    与其他编程语言相比,Python语言的操作类型更多样化。

    特别是星号(*),在Python中是一个用途广泛的操作符,而不仅仅用于两个数字相乘的运算之中。在本文中,我们将讨论星号的多种用途。

    这里总结了4种星号的应用场景:

    • 作为乘法和乘方的运算符
    • 表示序列中元素的重复
    • 用于收集参数(可以称之为“打包”)
    • 用于容器类对象的解包

    下面逐一进行说明。注意:很多人学Python过程中会遇到各种烦恼问题,没有人解答容易放弃。为此小编建了个Python全栈免费答疑.裙 :七衣衣九七七巴而五(数字的谐音)转换下可以找到了,不懂的问题有老司机解决里面还有最新Python实战教程免非下,,一起相互监督共同进步!

    乘法或乘方的运算符

    对此你一定不陌生,像乘法一样,Python中也内置了乘方运算符。

    >>> 2 * 3 
    6 
    >>> 2 ** 3 
    8 
    >>> 1.414 * 1.414 
    1.9993959999999997
    >>> 1.414 ** 1.414
    1.6320575353248798
    复制代码

    重复类列表的容器元素

    Python也支持类列表的容器类对象(即序列)与整数相乘,即为按照整数实现重复其中的元素数量。

    # Initialize the zero-valued list with 100 length
    zeros_list = [0] * 100 
    
    # Declare the zero-valued tuple with 100 length
    zeros_tuple = (0,) * 100  
    
    # Extending the "vector_list" by 3 times
    vector_list = [[1, 2, 3]] 
    for i, vector in enumerate(vector_list * 3):     
        print("{0} scalar product of vector: {1}".format((i + 1), [(i + 1) * e for e in vector]))
    # 1 scalar product of vector: [1, 2, 3]
    # 2 scalar product of vector: [2, 4, 6]
    # 3 scalar product of vector: [3, 6, 9]
    复制代码

    参数收集

    很多函数中,都会有不确定个数的参数。例如,如果我们不知道要提供多少个参数,或者因为什么原因必须传任意个参数等。

    在Python中有两类参数,一类是位置参数,另外一类是关键词参数,前者根据位置确定相应值,后者则是依据参数名称确定。

    在研究任意个位置/关键词参数之前,先讨论确定数量的位置参数和关键词参数。

    # A function that shows the results of running competitions consisting of 2 to 4 runners.
    def save_ranking(first, second, third=None, fourth=None):
        rank = {}
        rank[1], rank[2] = first, second
        rank[3] = third if third is not None else 'Nobody'
        rank[4] = fourth if fourth is not None else 'Nobody'
        print(rank)    
    
    # Pass the 2 positional arguments
    save_ranking('ming', 'alice')
    # Pass the 2 positional arguments and 1 keyword argument
    save_ranking('alice', 'ming', third='mike')
    # Pass the 2 positional arguments and 2 keyword arguments (But, one of them was passed as like positional argument)
    save_ranking('alice', 'ming', 'mike', fourth='jim')
    复制代码

    上述代码中的函数有2个位置参数:firstsecond,2个关键词参数:thirdfourth。位置参数不能省略,必须给所有的位置参数按照其正确的位置传值。然而,对于关键词参数,在定义函数的时候你可以设置默认值,如果调用函数的时候省略了相应的实参,会以默认值作为实参,即关键词参数可以省略。

    如你所见,关键词参数可以省略,所以,它们就不能在未知参数前面进行声明,如果按照下面的方式声明参数,就必然抛出异常。

    def save_ranking(first, second=None, third, fourth=None):
        ...
    复制代码

    但是,在save_ranking('alice', 'ming', 'mike', fourth='jim')调用中,提供了3个位置实参和一个关键词参数。是的,对于关键词参数,你也可以按照位置参数的方式传值,所对应的关键词能够接受依据位置所传的数据。按照此处的调用方法,'mike'就自动传给了third

    以上我们已经讨论了参数的基本含义,从上述示例中,我们也能看出来,上面所定义的函数不能接收任意个数的参数,因为该函数的参数是固定数量的。因此,需要对该函数进行改造,让它能够接收任意个参数,不论是位置参数还是关键词参数。看下面的示例:

    收集位置参数

    def save_ranking(*args):
        print(args) 
    save_ranking('ming', 'alice', 'tom', 'wilson', 'roy')
    # ('ming', 'alice', 'tom', 'wilson', 'roy')
    复制代码

    收集位置参数和关键词参数

    def save_ranking(*args, **kwargs):
        print(args)     
        print(kwargs)
    save_ranking('ming', 'alice', 'tom', fourth='wilson', fifth='roy')
    # ('ming', 'alice', 'tom')
    # {'fourth': 'wilson', 'fifth': 'roy'}
    复制代码

    在上面的示例中,*args意味着收集任意个数的位置参数,**kwargs意味着收集任意个数的关键词参数。这里的*args**kwargs可以称之为打包。

    如你所见,在上面我们按照位置或关键词传了任意个数的参数。按照位置传的参数被收集到元组中,并用变量args引用;以关键词传的参数则用变量kwargs引用为字典类型。

    前面提到过,关键词参数不能写在位置参数前面,所以,下面的定义方式是错误的:

    def save_ranking(**kwargs, *args):
        ...
    复制代码

    任意个数的参数很有价值,在很多开源项目中都能够看到,一般都是用*args或者**kwargs作为收集任意参数的名称,当然,你可以用其他名称,比如*requeired或者**optional等,都可以。只是对于开源项目而言,我们习惯使用*args**kwargs罢了。

    解包

    星号还可以用于对容器的解包,这与前面的参数收集类似,比如,有一个包含数据的列表、元组或者字典,还有一个收集任意参数的函数:

    from functools import reduce
    
    primes = [2, 3, 5, 7, 11, 13]
    
    def product(*numbers):
        p = reduce(lambda x, y: x * y, numbers)
        return p 
    
    product(*primes)
    # 30030
    
    product(primes)
    # [2, 3, 5, 7, 11, 13]
    复制代码

    因为product()能接收任意参数,我们本来需要将列表中的元素取出来,然后传给此函数。但在这里,如果以*primes的方式向函数提供primes列表数据,则primes所引用的列表会被解包,其中的每个素数都被传给函数,并被收集后用变量numbers引用。如果传该列表primes给函数,就不能解包,numbers所引用的元组中只有一个primes列表。

    对于元组也如此,对于字典,需要用**代替*

    headers = {
        'Accept': 'text/plain',
        'Content-Length': 348, 
        'Host': 'http://mingrammer.com' 
    }  
    
    def pre_process(**headers): 
        content_length = headers['Content-Length'] 
        print('content length: ', content_length) 
        
        host = headers['Host']
        if 'https' not in host: 
            raise ValueError('You must use SSL for http communication')  
            
    pre_process(**headers)
    # content length:  348
    # Traceback (most recent call last):
    #   File "<stdin>", line 1, in <module>
    #   File "<stdin>", line 7, in pre_process
    # ValueError: You must use SSL for http communication
    复制代码

    还有很多种解包的实现方式,甚至于不针对函数,只是从列表、元组中取出数据,并用动态变量引用。

    numbers = [1, 2, 3, 4, 5, 6]
    
    # The left side of unpacking should be list or tuple.
    *a, = numbers
    # a = [1, 2, 3, 4, 5, 6]
    
    *a, b = numbers
    # a = [1, 2, 3, 4, 5]
    # b = 6
    
    a, *b, = numbers
    # a = 1 
    # b = [2, 3, 4, 5, 6]
    
    a, *b, c = numbers
    # a = 1
    # b = [2, 3, 4, 5]
    # c = 6
    复制代码

    上述操作中说明,可以分别从列表或元组中解包,得到相应值,然后用*a*b引用解包所得数据,并将其打包为列表。这与前述任意个数的参数是同样的概念。

    结论

    以上简要介绍了Python语言中的星号(*),作为一个操作符,它有很多用途,特别是在“收集参数”中,显得很重要。但是,初学者容易在此处迷惑,所以,如果你是初学者,上面的内容要认真看一看。

    注意:很多人学Python过程中会遇到各种烦恼问题,没有人解答容易放弃。为此小编建了个Python全栈免费答疑.裙 :七衣衣九七七巴而五(数字的谐音)转换下可以找到了,不懂的问题有老司机解决里面还有最新Python实战教程免非下,,一起相互监督共同进步!
    本文的文字及图片来源于网络加上自己的想法,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

  • 相关阅读:
    Git分支管理策略
    嵌入式文件系统构建工具 busybox / buildroot / openwrt
    nodejs与c语言交互应用实例
    python与c语言交互应用实例
    websocket programming base on nodejs
    Using Bluetooth LE with Go
    nodejs
    linux ipc/its
    SAMA5D3 Xplained Board
    BlueZ
  • 原文地址:https://www.cnblogs.com/chengxuyuanaa/p/12692646.html
Copyright © 2020-2023  润新知