流畅的 Python(18):序列构成的数组 2.3.2

阅读数:11 2019 年 11 月 20 日 16:56

流畅的Python(18):序列构成的数组 2.3.2

内容简介
本书致力于帮助 Python 开发人员挖掘这门语言及相关程序库的优秀特性,避免重复劳动,同时写出简洁、流畅、易读、易维护,并且具有地道 Python 风格的代码。本书尤其深入探讨了 Python 语言的高级用法,涵盖数据结构、Python 风格的对象、并行与并发,以及元编程等不同的方面。

(元组拆包)

示例 2-7 中,我们把元组 ('Tokyo', 2003, 32450, 0.66, 8014) 里的元素分别赋值给变量 cityyearpopchgarea,而这所有的赋值我们只用一行声明就写完了。同样,在后面一行中,一个 % 运算符就把 passport 元组里的元素对应到了 print 函数的格式字符串空档中。这两个都是对元组拆包的应用。

元组拆包可以应用到任何可迭代对象上,唯一的硬性要求是,被可迭代对象中的元素数量必须要跟接受这些元素的元组的空档数一致。除非我们用 * 来表示忽略多余的元素,在“用 * 来处理多余的元素”一节里,我会讲到它的具体用法。Python 爱好者们很喜欢用元组拆包这个说法,但是可迭代元素拆包这个表达也慢慢流行了起来,比如“ PEP 3132—Extended Iterable Unpacking ”的标题就是这么用的。

最好辨认的元组拆包形式就是平行赋值,也就是说把一个可迭代对象里的元素,一并赋值到由对应的变量组成的元组中。就像下面这段代码:

>>> lax_coordinates = (33.9425, -118.408056)
>>> latitude, longitude = lax_coordinates # 元组拆包
>>> latitude
33.9425
>>> longitude
-118.408056

另外一个很优雅的写法当属不使用中间变量交换两个变量的值:

>>> b, a = a, b

还可以用 * 运算符把一个可迭代对象拆开作为函数的参数:

>>> divmod(20, 8)
(2, 4)
>>> t = (20, 8)
>>> divmod(*t)
(2, 4)
>>> quotient, remainder = divmod(*t)
>>> quotient, remainder
(2, 4)

下面是另一个例子,这里元组拆包的用法则是让一个函数可以用元组的形式返回多个值,然后调用函数的代码就能轻松地接受这些返回值。比如 os.path.split() 函数就会返回以路径和最后一个文件名组成的元组 (path, last_part):

>>> import os
>>> _, filename = os.path.split('/home/luciano/.ssh/idrsa.pub')
>>> filename
'idrsa.pub'

在进行拆包的时候,我们不总是对元组里所有的数据都感兴趣,_ 占位符能帮助处理这种情况,上面这段代码也展示了它的用法。

如果做的是国际化软件,那么 _ 可能就不是一个理想的占位符,因为它也是 gettext.gettext 函数的常用别名,gettext 模块的文档( https://docs.python.org/3/library/gettext.html )里提到了这一点。在其他情况下,_ 会是一个很好的占位符。

除此之外,在元组拆包中使用 * 也可以帮助我们把注意力集中在元组的部分元素上。

*来处理剩下的元素

在 Python 中,函数用 *args 来获取不确定数量的参数算是一种经典写法了。

于是 Python 3 里,这个概念被扩展到了平行赋值中:

>>> a, b, *rest = range(5)
>>> a, b, rest
(0, 1, [2, 3, 4])
>>> a, b, *rest = range(3)
>>> a, b, rest
(0, 1, [2])
>>> a, b, *rest = range(2)
>>> a, b, rest
(0, 1, [])

在平行赋值中,* 前缀只能用在一个变量名前面,但是这个变量可以出现在赋值表达式的任意位置:

>>> a, *body, c, d = range(5)
>>> a, body, c, d
(0, [1, 2], 3, 4)
>>> *head, b, c, d = range(5)
>>> head, b, c, d
([0, 1], 2, 3, 4)

另外元组拆包还有个强大的功能,那就是可以应用在嵌套结构中。

图灵地址 https://www.ituring.com.cn/book/1564

评论

发布