解包 Iterables
Python 3.x >= 3.0
在 Python 3 中,你可以在不知道其中的项的确切数量的情况下解压缩迭代,甚至可以使用变量保存可迭代的末尾。为此,你提供可以收集值列表的变量。这是通过在名称前放置一个星号来完成的。例如,解压缩 list
:
first, second, *tail, last = [1, 2, 3, 4, 5]
print(first)
# Out: 1
print(second)
# Out: 2
print(tail)
# Out: [3, 4]
print(last)
# Out: 5
注意 :使用*variable
语法时,variable
将始终是一个列表,即使原始类型不是列表。它可能包含零个或多个元素,具体取决于原始列表中的元素数量。
first, second, *tail, last = [1, 2, 3, 4]
print(tail)
# Out: [3]
first, second, *tail, last = [1, 2, 3]
print(tail)
# Out: []
print(last)
# Out: 3
同样,打开 str
:
begin, *tail = "Hello"
print(begin)
# Out: 'H'
print(tail)
# Out: ['e', 'l', 'l', 'o']
拆包 date
的例子; _
在这个例子中用作一次性变量(我们只对 year
值感兴趣):
person = ('John', 'Doe', (10, 16, 2016))
*_, (*_, year_of_birth) = person
print(year_of_birth)
# Out: 2016
值得一提的是,由于*
会占用不同数量的项目,因此在一项任务中你不能拥有两个*
s 用于相同的迭代 - 它不会知道第一次解包中有多少元素,第二次解包中有多少元素:
*head, *tail = [1, 2]
# Out: SyntaxError: two starred expressions in assignment
Python 3.x >= 3.5
到目前为止,我们已经讨论了在分配中拆包。*
和**
在 Python 3.5 中得到了扩展 。现在可以在一个表达式中进行多次解包操作:
{*range(4), 4, *(5, 6, 7)}
# Out: {0, 1, 2, 3, 4, 5, 6, 7}
Python 2.x >= 2.0
也可以将 iterable 解包为函数参数:
iterable = [1, 2, 3, 4, 5]
print(iterable)
# Out: [1, 2, 3, 4, 5]
print(*iterable)
# Out: 1 2 3 4 5
Python 3.x >= 3.5
打开字典包使用两个相邻的星星**
( PEP 448 ):
tail = {'y': 2, 'z': 3}
{'x': 1, **tail}
# Out: {'x': 1, 'y': 2, 'z': 3}
这允许重写旧值和合并字典。
dict1 = {'x': 1, 'y': 1}
dict2 = {'y': 2, 'z': 3}
{**dict1, **dict2}
# Out: {'x': 1, 'y': 2, 'z': 3}
Python 3.x >= 3.0
Python 3 删除了函数中的元组解包。因此,以下内容在 Python 3 中不起作用
# Works in Python 2, but syntax error in Python 3:
map(lambda (x, y): x + y, zip(range(5), range(5)))
# Same is true for non-lambdas:
def example((x, y)):
pass
# Works in both Python 2 and Python 3:
map(lambda x: x[0] + x[1], zip(range(5), range(5)))
# And non-lambdas, too:
def working_example(x_y):
x, y = x_y
pass
有关详细的基本原理,请参见 PEP 3113 。