Python 中星号作用:解包&打散


python中’*’和’**’的使用分两个方面,一个是计算,另一个是参数传递过程中元素的打包和解包。 

计算方面

‘*’和’**’在python中最常见的作用分别是‘相乘’和‘乘幂’,如下:

>>> a  = 2
>>> b = 3
>>> c = 5*6
>>> d = 4**3
>>> e = a*b
>>> f = a**b

传递、打包、解包方面

函数的可变参数

  • 对函数传递的参数进行打包(成元组tuple或字典dictionary)和拆解(分解成单个元素),其中元组的打包和解包使用单星号‘*’,字典的打包和拆解使用’**’。 
  • 打包,就是将传递给函数的任意多个(也可以是零个)非关键字参数/关键字参数打包成一个元组/字典(元组只能接收非关键字参数,字典只能接收关键字参数) 

当函数的参数前面有一个星号*的时候表示这是一个可变的位置参数,两个星号**表示是可变的关键字参数。

def foo(*args, **kwarg):
    for item in args:
        print item

    for k,v in kwarg.items():
        print k,v
    print 30*'='
if __name__ == '__main__':
    foo(1, 2, 3, a=4, b=5)
    foo(2, 3, a=4, b=5, c=1)

输出如下:

C:\Users\BigTree\AppData\Local\Programs\Python\Python36\python.exe "C:/Python S8/develops/Day 2 控制语句/星号用法.py"
1
2
3
a 4
b 5
**************************************************
2
3
a 4
b 5
c 1
**************************************************

Process finished with exit code 0

这样我们可以传入任意个数的参数。

解包/打散(unpack)参数

  • 拆解,就是将传递给函数的一个列表、元组或字典拆分成独立的多个元素然后赋值给函数中的参变量(包括普通的位置参数,关键字参数,元组也即*非关键字参数,字典也即**关键字参数)。
  • 在解字典时会有两种解法,一种使用*解,解出来传给函数的只有键值(.key)另一种是用**解,解出来的是字典的每一项。 

星号*把序列/集合解包(unpack)成位置参数,两个星号**把字典解包成关键字参数

下面通过示例来进一步加深理解:

def foo(*args, **kwarg):
    for item in args:
        print(item)
    for k,v in kwarg.items():
        print(k, v)
    print('*' * 50)

if __name__ == '__main__':
    #foo(1, 2, 3, a=4, b=5)
    #foo(2, 3, a=4, b=5, c=1)
    v = (1, 2, 4)
    v2 = [11, 15, 23]
    d = {'a':1, 'b':12}
    foo(v, d)
    foo(*v, **d)
    foo(v2, d)
    foo(*v2, **d)

输出如下:

C:\Users\BigTree\AppData\Local\Programs\Python\Python36\python.exe "C:/Python S8/develops/Day 2 控制语句/星号用法.py"
(1, 2, 4)
{'a': 1, 'b': 12}
**************************************************
1
2
4
a 1
b 12
**************************************************
[11, 15, 23]
{'a': 1, 'b': 12}
**************************************************
11
15
23
a 1
b 12
**************************************************

Process finished with exit code 0

上面的示例中如果v、v2、d没有加星号那么就当成了一个参数传递给了函数,如果加了星号那么就会解包后传递给函数。

foo(*d, **d)等价于foo(1, 2, 4, a=1, b=12)

几个注意点

可变位置参数*args是一个元组,是不可修改的。

>>> def foo(*args):
...     args[0] = 5
... 
>>> foo(1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in foo
TypeError: 'tuple' object does not support item assignment
>>> l = [1, 2, 3]
>>> foo(*l)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in foo
TypeError: 'tuple' object does not support item assignment

无论我们怎么传入参数,args都是一个tuple类型,不能进行修改。 
对于字典类型的如果只使用一个型号*那么传入的只是字典的键。

>>> def foo2(*args, **kwarg):
...     print args, kwarg
... 
>>> d = {'a':1, 'b':2, 'c':3}
>>> foo2(*d)
('a', 'c', 'b') {}
>>> foo2(**d)
() {'a': 1, 'c': 3, 'b': 2}

 


参考链接:http://blog.csdn.net/xiaoqu001/article/details/78823498





免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM