导读:本文总结了 Python 解包操作的方方面面,文章略长,看本文前,首先确保身边有多个不同版本 Python 解释器的电脑(公众号回复 conda ,了解如何安装多个环境),以便随时验证代码。看完记得收藏,方便查阅)

解包在英文里叫做 Unpacking,就是将容器里面的元素逐个取出来(防杠精:此处描述并不严谨,因为容器中的元素并没有发生改变)放在其它地方,好比你老婆去菜市场买了一袋苹果回来分别发给家里的每个成员,这个过程就是解包。Python 中的解包是自动完成的,例如:

>>> a, b, c = [1,2,3]

>>> a

1

>>> b

2

>>> c

3

如果列表中有3个元素,那么刚好如果列表中有3个元素,那么刚好可以分配给3个变量。除了列表对象可以解包之外,任何可迭代对象都支持解包,可迭代对象包括元组、字典、集合、字符串、生成器等实现了__next__方法的一切对象。

元组解包

>>> a,b,c = (1,2,3)

>>> a

1

>>> b

2

>>> c

3

字符串解包

>>> a,b,c = "abc"

>>> a

'a'

>>> b

'b'

>>> c

'c'

字典解包

>>> a,b,c = {"a":1, "b":2, "c":3}

>>> a

'a'

>>> b

'b'

>>> c

'c'

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

你可能见过多变量赋值操作,例如:

>>> a, b = 1, 2

>>> a

1

>>> b

2

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

>>> a = 1,

>>> a

(1,)

----------

>>> a = 1

>>> a

1

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

>>> a, b = 1, 2

>>> a, b = b, a

>>> a

2

>>> b

1

如果在解包过程中,遇到左边变量个数小于右边可迭代对象中元素的个数时该怎么办? 好比你们家有3口人,你老婆却买了4个苹果,怎么分配呢?

在Python2中,如果等号左边变量的个数不等于右边可迭代对象中元素的个数,是不允许解包的。但在 Python3 可以这么做了。这个特性可以在 PEP 3132 中看到。

>>> a, b, *c = [1,2,3,4]

>>> a

1

>>> b

2

>>> c

[3, 4]

>>>

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

>>> a, *b, c = [1,2,3,4]

>>> a

1

>>> b

[2, 3]

>>> c

4

这种语法有什么好处呢?它使得你的代码写起来更简洁,比如上面例子,在 Python2 中该怎么操作呢?思考3秒钟,再看答案。

>>> n = [1,2,3,4]

# 使用切片操作

>>> a, b, c = n[0], n[1:-1], n[-1]

>>> a

1

>>> b

[2, 3]

>>> c

4

以上是表达式解包的一些操作,接下来介绍函数调用时的解包操作。函数调用时,有时你可能会用到两个符号:星号*和 双星号**。

>>> 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

如果字典对象中的 key 不是 a,b,c,会出现什么情况?请读者自行测试。

总结一下,函数调用时,一个星号可作用于所有的可迭代对象,称为迭代器解包操作,作为位置参数传递给函数,两个星号只能作用于字典对象,称之为字典解包操作,作为关键字参数传递给函数。使用 *和 ** 的解包的好处是能节省代码量,使得代码看起来更优雅,不然你得这样写:

>>> d = {"a":1, "b":2, "c":3}

>>> func(a = d['a'], b=d['b'], c=d['c'])

1 2 3

>>>

到这里,解包还没介绍完,因为 Python3.5,也就是 PEP 448 对解包操作做了进一步的扩展, 在 3.5 之前的版本,函数调用时,一个函数中解包操作只允许一个* 和 一个**。从 3.5 开始,在函数调用中,可以有任意多个解包操作,例如:

# Python 3.4 中 print 函数 不允许多个 * 操作

>>> print(*[1,2,3], *[3,4])

File "", line 1

print(*[1,2,3], *[3,4])

^

SyntaxError: invalid syntax

>>>

再来看看 python3.5以上版本

# 可以使用任意多个解包操作

>>> print(*[1], *[2], 3)

1 2 3

从 3.5 开始可以接受多个解包,于此同时,解包操作除了用在函数调用,还可以作用在表达式中。

>>> *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}

在3.5之前的版本,你不得不写更多的代码:

>>> import copy

>>>

>>> c = copy.deepcopy(a)

>>> c.update(b)

>>> c

{'a': 1, 'b': 2, 'c': 3, 'd': 4}

最后给你总结一下:自动解包支持一切可迭代对象

python3中,开始支持更高级的解包操作,用星号操作使得等号左边的变量个数可以少于右边迭代对象中元素的个数。

函数调用时,可以用 * 或者 ** 解包可迭代对象

python3.5,函数调用和表达式中可支持更多的解包参数。

公众号:Python之禅

python解包什么意思_Python 解包骚操作,看这篇文章相关推荐

  1. python列表解析式如何使用_python列表推导式操作解析

    python列表推导式操作解析 这篇文章主要介绍了python列表推导式操作解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 基本格式 ​[表达式 ...

  2. python入门书籍推荐,看这篇文章就够,请!

    python入门书籍推荐,看这篇文章就够,请! 事实上,有关python的书籍很多很多,就当当网就有50000件和python有关的书籍,我特地去了当地的新华书店,蹲了大半天,回来给大家推荐,适合想学 ...

  3. python解包什么意思_python解包用法详解

    对于一堆资料,我们可以把它分给不同的人使用,这个分散的过程,我们可以看成是解包方法是实现.当然实际python解包的使用会相对复杂一点,我们会对常见的列表.函数等进行操作.下面我们就Python解包的 ...

  4. python包导入方式_python导包的几种方法(自定义包的生成以及导入详解)

    python 导入数据包的几种方法 1.直接导入整个数据包:improt 数据包 2.导入数据包中的某一个函数: from 数据包 improt 函数(当函数这一项为 * 时为导入整个数据包) 3. ...

  5. python包怎么用_python的包怎么应用

    python的包怎么应用 发布时间:2020-08-26 11:26:33 来源:亿速云 阅读:97 作者:Leah 这篇文章运用简单易懂的例子给大家介绍python的包怎么应用,代码非常详细,感兴趣 ...

  6. python导包的问题_python中包引入遇到的问题

    最近在用python的flask时候发现一点问题,代码组织如下 |-app |-__init__.py |-views.py |-operations.py |-xxx.py |-run.py 按照p ...

  7. python 抓包解析数据_Python抓包并解析json爬虫的完整实例代码

    Python抓包并解析json爬虫 在使用Python爬虫的时候,通过抓包url,打开url可能会遇见以下类似网址,打开后会出现类似这样的界面,无法继续进行爬虫: 例如: 需要爬取网页中第二页的数据时 ...

  8. python 类的知识点整理_Python基础知识点整理,看下你能答对几个

    python高薪就业(视频.学习路线.免费获取)​shimo.im 1.单行注释和多行注释 1. 单行注释 #. 2. 多行注释,前后三个单引号或双引号'''... '''; "" ...

  9. python微信公众号爬虫_Python爬取指定微信公众号所有文章!

    篇文章使用到的技术: mitmdump + 电脑版微信 先分析打开可视化抓包工具, 勾选https代理.然后打开电脑版微信 任意点击一个公众号,再点击查看历史消息 注:想学习Python的小伙伴们 可 ...

最新文章

  1. python快速编程入门课后简答题答案-Python编程:从入门到实践(第2版)第1章习题答案...
  2. Shell 文件包含
  3. poj 1830 开关问题 高斯消元
  4. Yolov5目标检测模型运行遇到的相关问题汇总
  5. 动态规划 0-1背包问题 滚动数组
  6. 怎么做最棒的有效外链
  7. 安装官方 Synaptics 驱动,终于解决 HP Pavilion G4 笔记本 讨厌的触摸板锁定问题!...
  8. 1.2.3 TCP/PI参考模型(应用层、传输层、网际层、网络接口层)、五层参考模型(应用层、传输层、网络层、数据链路层、物理层)、OSI与TCP/IP参考模型比较(转载)
  9. 20165212四则运算2
  10. 使用PHP输出中文JSON字符串
  11. 计算机毕业设计nodejs宠物寄存管理系统
  12. 数据结构-栈操作-用链表实现栈基本操作
  13. WGS84 UTM 坐标系及UTM投影分带标准
  14. java 拍照后加上日期水印_有什么软件能批量给照片添加拍照日期的水印?
  15. 许奔创新社-第27问:创新者们如何进行跨界交流?
  16. layui 使用文档总结
  17. 汤姆猫信使: 折翼的信使
  18. 【原创】年轻人接受指点,但不接受指指点点
  19. 中国移动物联网开放平台OneNET学习笔记(1)——设备接入(MQTT协议)OneNET Studio篇
  20. Nginx 反向代理https

热门文章

  1. 7-41 计算阶乘和
  2. 使用Visual Studio调试BGFX的Shader
  3. 应用于语义分割问题的深度学习技术综述
  4. [Vulhub] ThinkPHP漏洞合集
  5. 【转】unbuntu 12.10/13.04 安装ibus中文输入法 及解决无法显示首选项bug
  6. HTTP的get和post请求方法以及HTTP接口
  7. 经验分享:2021最新Android开发者学习路线,深度解析,值得收藏
  8. 农村的我在1024分享开始杭漂的经历和心酸,我们一起共勉~
  9. 前端JavaScript基础学习
  10. 《电脑报2014年》更新至第51期