1. 定义

什么是元组解包?元组解包也叫‘元组拆包’,‘迭代对象解包’
等。也就是把批量的数据进行批量的赋值。当然不只是tuple,任何可迭代对象都支持解包,还包括dict、set、string等一切实现了__next__方法的
可迭代对象。

2.  普通示例

下面的是很经典且普通的示例,(Python2中) 右边可迭代对象中的元素个数要和左边的保持一致,否则会报错!
a1, b1, c1 = (1, 2, 3) print(a1, b1, c1) # 1 2 3 a2, b2, c2 = [1, 2, 3]
print(a2, b2, c2) # 1 2 3 a3, b3, c3 = {'a': 123, 'b': 37, 'c': 34}.items()
print(a3, b3, c3) # ('a', 123) ('b', 37) ('c', 34) a4, b4, c4 = {'a': 123, 'b':
37, 'c': 34}.keys() print(a4, b4, c4) # a b c a5, b5, c5 = {'a': 123, 'b': 37,
'c': 34}.values() print(a5, b5, c5) # 123 37 34 a6, b6, c6 = 'hel' print(a6,
b6, c6) # h e l
3. 多变量赋值

多变量赋值和交换其实也是元组解包的一种,对于下面的操作:
x, y = 1, 2
实质上上述操作是这样的:首先创建了一个1,2这个元组,然后遍历这个元组,将拿到的两个值按分别赋值给x 和 y。也就是说下面的这些写法都是等价的:
x, y = 1, 2 x, y = (1, 2) (x, y) = 1, 2 (x, y) = (1, 2)
 4. 单元素解包

单元素解包也就是序列中只有一个元素的解包过程,虽然可能不常用,但是我们一定要知道!

如下的这种方式,在左侧一定要加逗号,那么左边的变量才为右侧元组或者列表解包的结果
a, = (1, ) b, = [1, ] print(type(a), a) # <class 'int'> 1 print(type(b), b) #
<class 'int'> 1
而这种方式,就是普通的变量赋值,等号左侧没有逗号,要和上面的形式区分开
a1 = (1, ) b1 = [1, ] print(type(a1), a1) # <class 'tuple'> (1,)
print(type(b1), b1) # <class 'list'> [1]
5. 带 * 号的解包

我在上面说到,右边可迭代对象中的元素个数要和左边的保持一致。但是这是python2中的特性,在python3 中通过增加 * 来表示任意数量的
,从而实现更简洁的解包方式。如下:

【注意】

* *号可以放在左侧的任意位置,但位置不一样,赋值结果也不同
* 先给非星号的变量赋值,剩下的元素转换成 list 给*号的变量赋值
* * 号不能在一个赋值语句中同时出现两次或者两次以上
* 解包字典,是以元组的形式来保存键值对,但解包出来不一定是顺序的
* 对于这种单纯的等号赋值的语句,左侧是没有 ** 号这种形式的 a, b, *c = (1, 2, 3, 4, 5, 6) # tuple
print(a, b, c) # 1, 2, [3, 4, 5, 6] a1, b1, *c1 = [1, 2, 3, 4, 5, 6] # list
print(a1, b1, c1) # 1 2 [3, 4, 5, 6] a2, b2, *c2 = range(1, 7) # range
print(a2, b2, c2) # 1 2 [3, 4, 5, 6] a3, b3, *c3 = 'hello' # string print(a3,
b3, c3) # h e ['l', 'l', 'o'] a4, b4, *c4 = {'a': 1, 'b': 2, 'c': 3, 'd':
4}.items() # dict print(a4, b4, c4) # ('a', 1) ('b', 2) [('c', 3), ('d', 4)]
以元组形式保存键值对 a5, *b5, c5 = [1, 2, 3, 4, 5, 6] # 任意位置的 * 号 print(a5, b5, c5) # 1
[2, 3, 4, 5] 6
6. 表达式中的解包

表达式中应用解包,可以完成列表(元组、字典)等可迭代对象的拼接操作,避免了应用for循环进行拼接的冗余代码!本质上 解包
的底层操作就是遍历右侧对象,依次取出来赋值给左侧变量。

【注意】

* Python3.5之前是不允许带有两个或两个以上的*号的!!之后是允许的
* 列表/元组在python表达式中解包用* 号,字典用 ** 号  # 列表 / 元组 在python表达式中的操作 nums = [1, 2, 3]
nums1 = [2, 3, 4] total = [*nums, *nums1] # [1, 2, 3, 2, 3, 4] total1 = [*nums,
3, 4] # [1, 2, 3, 3, 4] total2 = [1, *nums, 4] # [1, 1, 2, 3, 4] a = (1, 3, 4)
b = (3, 3, 4) c = [*a, *b] # [1, 3, 4, 3, 3, 4] d = (*a, *b) # (1, 3, 4, 3, 3,
4) # 字典 在python表达式中的操作 dict1 = {"a": 1, 'b': 2, 'c': 4} dict2 = {**dict1, 'd':
9} # {'a': 1, 'b': 2, 'c': 4, 'd': 9}
7.  函数中的解包

【注意】:

* 函数中的解包是在 传递参数 的时候加 * 号,而可变参数是在 函数定义 的时候加 * 号
* 字典同1所述,只不过把 * 号变成了 ** 号
* 当函数传递多个带*号的参数时,会类似于表达式中一样,先自动拼接起来,然后再传参 def show(*args): print(args) def
dict(**kwargs): print(kwargs) nums = [1, 2, 3] nums1 = [1, 2, 3] dict1 = {'a':
1, 'b': 2, 'c': 3} dict2 = {'d': 9} show(*nums) # (1, 2, 3) show(*nums, *nums1)
# (1, 2, 3, 1, 2, 3) dict(**dict1) # {'a': 1, 'b': 2, 'c': 3} dict(**dict1,
**dict2) # {'a': 1, 'b': 2, 'c': 3, 'd': 9}
8. 深度解包

在前面的解包操作都是 浅度 的,因为它只进行了一层的解包,接下来我将展示深度解包操作:

其实也很好理解,按照右侧的模式,左侧再来一个一样的变量接着就行
a, (b1, b2, b3), c = (1, (2, 3, 3), 5) print(a, b1, b2, b3, c) # 1 2 3 3 5 d,
f, (e1, e2, e3) = 1, 5, (2, 3, 3) print(d, f, e1, e2, e3) # 1 5 2 3 3

上面的总结,基本上涵盖了python解包的所有操作,如果有需要增加的,或者哪里不对的地方,欢迎留言~

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信