147 Распаковка товаров

В 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.5 . Теперь возможно иметь несколько операций распаковки в одном выражении:

 {*range(4), 4, *(5, 6, 7)}
# Out: {0, 1, 2, 3, 4, 5, 6, 7}

 

Также возможно распаковать итерацию в аргументы функции:

 iterable = [1, 2, 3, 4, 5]
print(iterable)
# Out: [1, 2, 3, 4, 5]
print(*iterable)
# Out: 1 2 3 4 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 убрал распаковку кортежей в функциях. Следовательно, следующее не работает в 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 для детального обоснования.