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