python3下的 * 和 ** 号使用方法

最常见的是:在函数中,用 * args和**kwargs表示可变参数和仅使用key = value的参数。另外最近碰到了一个,用于unpacking dictionary的*号用法。下面讨论一下:

  1. *用于展开list、tuple、dict,直接访问里面的元素
    Eg:
def main():
    a = [1,2,3,4]
    b = (1,2,3,4)
    c = {'key1': 1, 'key2': 2}
    print(*a, end = '\t')
    print(a)
    print(*b, end = '\t')
    print(b)
    print(*c, end = '\t')
    print(c)

if __name__ == '__main__':
    main()

结果为:

1 2 3 4	[1, 2, 3, 4]
1 2 3 4	(1, 2, 3, 4)
key1 key2	{'key1': 1, 'key2': 2}

和直接print对比很明显可以发现,这里的“展开”字典,实际上只是访问了字典的key而没有访问字典的value

这个用法甚至允许不同类型的变量合并在一起,比如:

a = [1,2,3,4]
b = (1,2,3,4)
c = {'key1': 1, 'key2': 2}
print(*a,*b,*c)
1 2 3 4 1 2 3 4 key1 key2

因为传入函数的参数是展开了的参数,所以实际上前面的代码,传给print的参数是4个,后面的代码传给print的参数是8个,这一点可以通过自己定义函数很明显体会到:

def f1(a,b,c,d):
	print(a,b,c,d, end = '\t')

f1(*a)
f1(*a,*b)

运行结果是:

1 2 3 4
TypeError: f1() takes 4 positional arguments but 8 were given

那么print是怎么做到既可以接受4个参数,又可以接受8个参数的呢?看下面:

  1. *args传递可变长参数、**kwargs传递使用key的可变长参数
    Eg:
def f1(*args):
    for a in args:
        print(a, end = '')
    print()

def f2(**kwargs):
    for k,v in kwargs.items():
        print(k,v)

def main():
    f1(1)
    f1(1,2,3)
    f2(name = 'name_name', key = 'key_key')
    f2(name = 'key')

if __name__ == "__main__":
    main()

输出结果为:

1
123
name name_name
key key_key
name key

回答1最后提出的问题,print函数的定义,肯定是print(*args)这样的形式。2个结合一下:

def f1(*args):
    for a in args:
        print(a, end = '')
    print()

def f2(**kwargs):
    for k,v in kwargs.items():
        print(k,v, end = '')
    print()
    print(kwargs)

def main():
    b = [1,2,3,4]
    f1(b)
    f1(*b)
    a = {"name": 'name_name', "key": 'key_key'}
    f2(**a)

if __name__ == "__main__":
    main()

结果为:

[1, 2, 3, 4]
1234
name name_namekey key_key
{'name': 'name_name', 'key': 'key_key'}

第一行输出[1, 2, 3, 4]是因为把b当作1个参数输入f1了,所以执行print(a, end = '')这一句,没有换行,循环1次就退出来,执行print()再换行
第二行输出1234,是因为b的4个元素作为4个参数输入f1,所以循环4次,循环内print不换行,所以1234是紧邻的,循环后才换行
第三行输出,是因为**a展开了a的元素,把2个key-value对作为参数输入f2,所以循环执行2次,循环内print不换行,因此name_namekey就是紧邻着的,循环结束后换行,所以第四行输出执行print(kwargs),实际上就是直接打印字典了。

可以看到在f2函数里面,kwargs实际上就是输入的字典,但是为什么要写**kwargs,而不直接写f2(input_dict)呢?因为f2(**kwargs)的输入参数可以是多个字典,但f2(input_dict)只能用1个字典作为输入。

最后总结一下:

  1. *符号可以用作展开list、tuple、dict里面的元素(字典只能展开key)
  2. 函数定义时,如果输入参数用了*args,**kwargs,表示输入参数是可变长度的,前者是普通的可变长度参数,后者是key-value对形式的可变长度参数。
  3. 上面2点结合,在函数内就可以访问多个输入的参数合并到一起的变量了。

参考链接

https://treyhunner.com/2018/10/asterisks-in-python-what-they-are-and-how-to-use-them/
https://stackoverflow.com/questions/36901/what-does-double-star-asterisk-and-star-asterisk-do-for-parameters

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值