美文网首页
正确理解python ** 双星 和 * 单星

正确理解python ** 双星 和 * 单星

作者: Helen_Cat | 来源:发表于2019-03-23 14:33 被阅读0次

    如果我们经常看一些python包的原始的代码,经常会发现 他们定义的方法会在最后参数列表位置 包含 *args 或者 **kwargs, 这样的书写可以增加方法的健壮性,除了必须要的参数和默认参数,多余的参数再多也不会报错,,那我们还是 需要理解一下 ** *

    单星 *
    1.一般用在 元组 tuple 和list 列表,加上* 以后等于给他 加上了 位置属性, 类似索引
    举例

    def foo(a,b):
        print(a+b)
    pos_list=(3,54)
    
    pai_list=(3,54,21,34)
    foo(*pos_list)
    

    本来 函数 foo 需要两个参数 a 和b ,刚好你有 两个列表pos_list 有两个元素,pai_list有四个元素,
    如果你直接 foo(pos_list) 是报错的,foo 需要的是两个参数,而且根据函数体,我们可以判断需要的是数字类型的变量,你传入一个列表就当然报错了,
    怎么办,把列表的元素取出来呢
    最简单就是这样,把列表的元素按索引取出来
    foo( pos_list[0], pos_list[1]),这个是可以正常执行的,不过未免有点低效,
    有没有办法 直接把 pos_list[0]映射给参数a, pos_list[1]映射给参数b ?

    当然有 就是 列表前加星号* ,有点像c语言取地址符 ,这样列表 其实就带了position属性
    只要列表的元素个数和 参数个数相等,就可以一一对应。
    foo(*pos_list) 可以正常执行

    那如果 列表元素个数超过 参数个数,直接加星号就会报给的参数过多的错误, 不过我们可以使用切片 的方法来解决

    def foo(a,b):
        print(a+b)
    
    pai_list=(3,54,21,34)
    foo(*pai_list[0:2])
    

    2.单星也会用在循环中,比如 合并两个或者多个list

    pos_list=(3,54)
    
    pai_list=(3,54,21,34)
    
    res_list=[  *pos_list,*pai_list]
    print(res_list)
    >>  [3, 54, 21, 34, 3, 54]
    
    tuple_res=(*lis,*lisz)
    print(tuple_res)
    >> (3, 54, 21, 34, 3, 54)
    
    

    双星 **
    1.双星 主要是应用在键值对上,一般就是字典dict ,加两个星 这个其实就是把字典的key 映射为函数参数名,value 映射为参数值,这里有一个条件,就是 key 要和参数名 对应上, 否则会报错,而且 数据类型也要保证是对应的

    def foo(a,b):
        print(a+b)
    
    dic={'a':56,'b':45}
    foo(**dic)
    

    2.双星 会应用到循环上 会是 非常高效和优雅的方式
    比如你打算合并两个 字典 dict_1 dict_2

    dic_1={'a':56,'b':45}
    dic_2={'c':26,'d':15}
    dic_res={ **dic_1,**dic_2}
    
    print(dic_res)
    >>
    {'a': 56, 'c': 26, 'b': 45, 'd': 15}
    

    需要注意的是如果两个字典出现重复key 的话,有一个会被覆盖掉
    基于这种方式 你甚至可以一口气合并七八个字典

    dic_1={'a':56,'b':45}
    dic_2={'c':26,'d':15}
    dic_3={'e':26,'r':15}
    dic_res={ **dic_1,**dic_2,**dic_3}
    
    print(dic_res)
    >> {'e': 26, 'd': 15, 'r': 15, 'a': 56, 'b': 45, 'c': 26}
    

    3 在函数声明中看到 参数 单星和双星 含义就是 单星意味着 接受不定参数,并且把这些不定参数当做tuple来处理,双星参数则意味着 接受不定参数的键值对,并且把键映射为参数名,值映射为参数值 或者说 如果你输入了 多个参数及值,则会把他映射成字典dict

    
    def foo(*t):
        print(t)
    
    >>> foo(1, 2)
    (1, 2)
    
    def foo(**d):
        print(d)
    
    >>> foo(x=1, y=2)
    {'y': 2, 'x': 1}
    
    dic_1={'a':56,'b':45}
    foo(**dic_1)
    >>{'a':56,'b':45} 
    

    另外 * 作为列表的不定参数子集存在

    >>> x, *xs = (1, 2, 3, 4)
    >>> x
    1
    >>> xs
    [2, 3, 4]
    
    >>> *xs, x = (1, 2, 3, 4)
    >>> xs
    [1, 2, 3]
    >>> x
    4
    
    >>> x, *xs, y = (1, 2, 3, 4)
    >>> x
    1
    >>> xs
    [2, 3]
    >>> y
    4
    
    >>> for (x, *y, z) in [ (1, 2, 3, 4) ]: print(x, y, z)
    ...
    1 [2, 3] 4
    

    参考

    In a function call
    *t means "treat the elements of this tuple as positional arguments to this function call."
    
    def foo(x, y):
        print(x, y)
    
    >>> t = (1, 2)
    >>> foo(*t)
    1 2
    Since v3.5, you can also do this in a list/tuple/set literals:
    
    >>> [1, *(2, 3), 4]
    [1, 2, 3, 4]
    **d means "treat the key-value pairs in the dictionary as additional named arguments to this function call."
    
    def foo(x, y):
        print(x, y)
    
    >>> d = {'x':1, 'y':2}
    >>> foo(**d)
    1 2
    Since v3.5, you can also do this in a dictionary literals:
    
    >>> d = {'a': 1}
    >>> {'b': 2, **d}
    {'b': 2, 'a': 1}
    In a function signature
    *t means "take all additional positional arguments to this function and pack them into this parameter as a tuple."
    
    def foo(*t):
        print(t)
    
    >>> foo(1, 2)
    (1, 2)
    **d means "take all additional named arguments to this function and insert them into this parameter as dictionary entries."
    
    def foo(**d):
        print(d)
    
    >>> foo(x=1, y=2)
    {'y': 2, 'x': 1}
    In assignments and for loops
    *x means "consume additional elements in the right hand side", but it doesn't have to be the last item. Note that x will always be a list:
    
    >>> x, *xs = (1, 2, 3, 4)
    >>> x
    1
    >>> xs
    [2, 3, 4]
    
    >>> *xs, x = (1, 2, 3, 4)
    >>> xs
    [1, 2, 3]
    >>> x
    4
    
    >>> x, *xs, y = (1, 2, 3, 4)
    >>> x
    1
    >>> xs
    [2, 3]
    >>> y
    4
    
    >>> for (x, *y, z) in [ (1, 2, 3, 4) ]: print(x, y, z)
    ...
    1 [2, 3] 4
    

    https://stackoverflow.com/questions/21809112/what-does-tuple-and-dict-means-in-python

    https://python-reference.readthedocs.io/en/latest/docs/operators/dict_unpack.html

    相关文章

      网友评论

          本文标题:正确理解python ** 双星 和 * 单星

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