解压序列赋值

任何的序列(或者是可迭代对象)可以通过一个简单的赋值语句解压并赋值给多个变量。
唯一的前提就是变量的数量必须跟序列元素的数量是一样的。
代码如下:

>>> p = (4, 5)
>>> x, y = p
>>> x
4
>>> y
5
>>>
>>> data = [ 'ACME', 50, 91.1, (2012, 12, 21) ]
>>> name, shares, price, date = data
>>> name
'ACME'
>>> date
(2012, 12, 21)
>>> name, shares, price, (year, mon, day) = data
>>> name
'ACME'
>>> year
2012
>>> mon
12
>>> day
21
>>>

如果变量个数和序列元素的个数不匹配,会产生一个异常。
代码如下:

>>> p = (4, 5)
>>> x, y, z = p
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: need more than 2 values to unpack
>>>

实际上,这种解压赋值可以用在任何可迭代对象上面,而不仅仅是列表或者元组。包括字符串,文件对象,迭代器和生成器。
代码如下:

>>> s = 'Hello'
>>> a, b, c, d, e = s
>>> a
'H'
>>> b
'e'
>>> e
'o'
>>>

有时候,你可能只想解压一部分,丢弃其他的值。对于这种情况 Python 并没有提供特殊的语法。但是你可以使用任意变量名去占位,到时候丢掉这些变量就行了。
代码如下:

>>> data = [ 'ACME', 50, 91.1, (2012, 12, 21) ]
>>> _, shares, price, _ = data
>>> shares
50
>>> price
91.1
>>>

解压可迭代对象赋值给多个变量
代码如下:

>>> record = ('Make', '119***445@qq.com', '996-545-1312', '389-565-1282')
>>> name, email, *phone_numbers = record
>>> name
'Make'
>>> email
'119***445@qq.com'
>>> phone_numbers
['996-545-1312', '389-565-1282']
>>>

值得注意的是上面解压出的 phone_numbers 变量永远都是列表类型,不管解压的电话号码数量是多少(包括 0 个)。所以,任何使用到 phone_numbers 变量的代码就不需要做多余的类型检查去确认它是否是列表类型了。
星号表达式也能用在列表的开始部分。

>>> *trailing, current = [10, 8, 7, 1, 9, 5, 10, 3]
>>> trailing
[10, 8, 7, 1, 9, 5, 10]
>>> current
3

星号解压语法在字符串操作的时候也会很有用,比如字符串的分割。
代码如下:

>>> line = 'nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false'
>>> uname, *fields, homedir, sh = line.split(':')
>>> uname
'nobody'
>>> homedir
'/var/empty'
>>> sh
'/usr/bin/false'
>>>

有时候,你想解压一些元素后丢弃它们,你不能简单就使用 * ,但是你可以使用一个普通的废弃名称,比如 _ 或者 ign (ignore)。

>>> record = ('ACME', 50, 123.45, (12, 18, 2012))
>>> name, *_, (*_, year) = record
>>> name
'ACME'
>>> year
2012
>>>
posted @ 2020-02-13 10:08  阳神  阅读(133)  评论(0编辑  收藏  举报