Python中的组包与解包

前言:*args和 **kwargs是在python的代码中经常用到的两个参数,初学者对这两个参数的理解可能仅仅限于args是用于接收多余的未命名参数,*kwargs用于接收形参中的命名参数,其中args是一个元组类型,而kwargs是一个字典类型的数据。 其实这两个参数还涉及到了python中的一个重要的知识点,组包与解包。

一、组包

在Python中,组包的操作是自动完成的,将多个值同时赋给一个变量时,解释器会进行自动组包操作。

组包:自动操作,当等号右边有多个数据的时候,会自动包装成为元组。

a = 10, 20, 30
print(a)
# (10, 20, 30)

二、解包

解包就是把一个容器拆开、分解,在Python中的解包是自动完成的。

变量数量 = 元素数量,会进行逐一赋值。

在Python中任何可迭代对象都支持解包,可迭代对象包括列表、元组、字典、集合、字符串、生成器等实现了__next__方法的一切对象。

  1. 解包的意义就是将传递给函数的一个列表,元组,字典,拆分成独立的多个元素然后赋值给函数中的形参变量。
  2. 解包字典有两种解法,一种用*解的只有key,一种用**解的有key、value。但是这个方法**只能在函数定义中使用。

1、表达式

  1. 列表解包
a, b, c = [1, 2, 3]
print(a, b, c)
# 1 2 3

  1. 元祖解包
a, b, c = (1, 2, 3)
print(a, b, c)
# 1 2 3

  1. 字符串解包
a, b, c = "abc"
print(a, b, c)
# a b c

  1. 字典解包
a, b, c = {"a": 1, "b": 2, "c": 3}
print(a, b, c)
# a b c

字典解包后,只会把字典的key取出来,value 则丢掉了。

  1. 多变量赋值
a, b = 1, 2
print(a, b)
# 1 2

以上操作,本质上也是自动解包过程,等号右边其实是一个元组对象 (1, 2),有时候我们代码不小心多了一个逗号 ,,就变成了元组对象。

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

我们在写代码的时候需要特别注意:在 Python 中,交换两个变量非常方便,本质上也是自动解包过程。

a, b = 1, 2
a, b = b, a
print(a, b)
# 2 1

  1. 参数不够的情况
a, b, *c = [1, 2, 3, 4]
print(a, b, c)
# 1 2 [3, 4]

这种语法就是在某个变量面前加一个星号,而且这个星号可以放在任意变量,每个变量都分配一个元素后,剩下的元素都分配给这个带星号的变量。

a, *b, c = [1, 2, 3, 4]
print(a, b, c)
# 1 [2, 3] 4

2、函数

  1. 函数调用

函数调用时,有时你可能会用到两个符号:星号*和 双星号**

def func(a, b, c):
    print(a, b, c)

func(1, 2, 3)
# 1 2 3

func函数定义了三个位置参数 a,b,c,调用该函数必须传入三个参数,除此之外,你也可以传入包含有3个元素的可迭代对象。

func(*[1, 2, 3])
# 1 2 3
func(*(1, 2, 3))
# 1 2 3
func(*"abc")
# a b c
func(*{"a": 1,"b": 2,"c": 3})
# a b c

函数被调用的时候,使用星号*解包一个可迭代对象作为函数的参数。字典对象,可以使用两个星号,解包之后将作为关键字参数传递给函数。

func(**{"a": 1,"b": 2,"c": 3})
# 1 2 3

**符号作用的对象是字典对象,它会自动解包成关键字参数 key=value 的格式:

func(a=1, b=2, c=3)
# 1 2 3

  1. 多解包操作
# 可以使用任意多个解包操作
print(*[1], *[2], 3)
# 1 2 3

于此同时,解包操作除了用在函数调用,还可以作用在表达式中。

*range(4), 4
# (0, 1, 2, 3, 4)
[*range(4), 4]
# [0, 1, 2, 3, 4]
{*range(4), 4}
# {0, 1, 2, 3, 4}
{"x": 1, **{"y": 2}}
# {"x": 1, "y": 2}

可以看出,这种语法使得我们的代码更加优雅了,例如拼接两个列表可以这样:

list1 = [1, 2, 3]
list2 = range(3, 6)
[*list1, *list2]
# [1, 2, 3, 3, 4, 5]

可不可以直接用 + 操作呢?不行,因为 list 类型无法与 range 对象相加,你必须先将 list2 强制转换为 list 对象才能做 +操作。再来看一个例子:如何优雅的合并两个字典

a = {"a": 1, "b": 2}
b = {"c": 3, "d": 4}
{**a, **b}
# {"a": 1, "b": 2, "c": 3, "d": 4}

三、总结

  1. 组包实则是将多个值赋给一个变量,自动组成的是元组。
  2. 自动解包支持一切可迭代对象。
  3. python3中,支持更高级的解包操作,用星号操作使得等号左边的变量个数可以少于右边迭代对象中元素的个数。
  4. 函数调用时,可以用*或者**解包可迭代对象,作为参数传递。
  5. python3.5,函数调用和表达式中可支持更多的解包操作。
希望本文对你有所帮助~~如果对软件测试、接口测试、自动化测试、面试经验交流感兴趣可以加入我们。642830685,免费领取最新软件测试大厂面试资料和Python自动化、接口、框架搭建学习资料!技术大牛解惑答疑,同行一起交流。
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 解包在英文里叫做 Unpacking,就是将容器里面的元素逐个取出来(防杠精:此处描述并不严谨,因为容器中的元素并...
    妄心xyx阅读 490评论 0 1
  • 解包在英文里叫做 Unpacking,就是将容器里面的元素逐个取出来(防杠精:此处描述并不严谨,因为容器中的元素并...
    _Cappuccino_阅读 371评论 0 0
  • 任何可迭代对象都支持解包,可迭代对象包括元组、字典、集合、字符串、生成器等实现了_next__方法的一切对象。列表...
    cook__阅读 2,195评论 0 2
  • python中的解包你可以这个样子来理解:一个list是一个整体,想把list中的每一个元素都当成一个个个体剥离出...
    龙皓晨阅读 1,278评论 0 1
  • python中的解包可以这样理解:一个list是一个整体,想把list中每个元素当成一个个个体剥离出来,这个过程就...
    龙皓晨阅读 4,337评论 0 1

友情链接更多精彩内容