python巧用拆包

  Python中,多变量赋值使得代码更精练易读,例如x, y, z = 3, 4, 5 。能如此赋值的原因实际为其将"="右侧的值当作一个元组,"="左侧再使用与元组个数相等的变量对其进行拆包,逐个赋值

>>> x, y, z = 3, 4, 5
>>> x
3
>>> y
4
>>> z
5
>>> 
View Code
  任何的序列(或者是可迭代对象)可以通过一个简单的赋值语句解压并赋值给多个变量。 前提是变量的数量必须和序列元素的数量是一样的
>>> 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
>>>
View Code

  如果变量个数与序列元素个数不匹配,则会引发一个异常。

>>> p = (3, 4)
>>> x, y, z = p
Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    x, y, z = p
ValueError: not enough values to unpack (expected 3, got 2)
>>> 
View Code

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

  而当我们在进行拆包的时候,可能有些数据并不是我们需要的,此时可以使用"_"来占位

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

  针对变量个数与序列元素个数不匹配时会引发异常的问题,python提供了另一种扩展语法,即"*"表达式

  当拆包时,在变量前加上"*"之后,该变量就变成了一个列表类型。

>>> record = ('Dave', 'dave@example.com', '773-555-1212', '847-555-1212')
>>> name, email, *phone_numbers =record
>>> name
'Dave'
>>> email
'dave@example.com'
>>> phone_numbers
['773-555-1212', '847-555-1212']
>>>
>>>
>>>
>>> *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'
>>>
View Code

  扩展的迭代解压语法是专门为解压不确定个数或任意个数元素的可迭代对象而设计的。通常,这些可迭代对象的元素结构有确定的规则(比如第1个元素后面都是电话号码)

  这种扩展语法,带"*"的变量只能有一个,否则会引发一个异常

>>> data = ['ACME', 50, 91.1, (2012, 12, 21)]
>>> a, *b, *c = data
SyntaxError: two starred expressions in assignment
>>> 
View Code

  参考文档:python_cookbook(第3版)

  

posted @ 2023-08-30 11:08  Maserati~  阅读(121)  评论(0)    收藏  举报