Деструктуризация (упаковка и распаковка) списка

Введение

Примеры

  • Разрушающее задание

    В присваиваниях вы можете разбить Iterable на значения, используя синтаксис «распаковка»:

    Разрушение как ценности

     a, b = (1, 2)
    print(a)
    # Prints: 1
    print(b)
    # Prints: 2
    
     

    Если вы попытаетесь распаковать больше длины итерируемой, вы получите ошибку:

     a, b, c = [1]
    # Raises: ValueError: not enough values to unpack (expected 3, got 1)
    
     

    Разрушение в виде списка

    Вы можете распаковать список неизвестной длины, используя следующий синтаксис:

     head, *tail = [1, 2, 3, 4, 5]
    
     

    Здесь мы извлекаем первое значение как скаляр, а остальные значения как список:

     print(head)
    # Prints: 1
    print(tail)
    # Prints: [2, 3, 4, 5]
    
     

    Что эквивалентно:

     l = [1, 2, 3, 4, 5]
    head = l[0]
    tail = l[1:]
    
     

    Он также работает с несколькими элементами или элементами в конце списка:

     a, b, *other, z = [1, 2, 3, 4, 5]
    print(a, b, z, other)
    # Prints: 1 2 5 [3, 4]
    
     

    Игнорирование значений в деструктурирующих заданиях

    Если вы заинтересованы только в данном значении, можно использовать _ , чтобы указать , что вы не заинтересованы. Примечание: это будет еще множество _ , просто большинство людей не используют его в качестве переменной.

     a, _ = [1, 2]
    print(a)
    # Prints: 1
    a, _, c = (1, 2, 3)
    print(a)
    # Prints: 1
    print(c)
    # Prints: 3
    
     

    ## Игнорирование списков в деструктурирующих присваиваниях Наконец, вы можете игнорировать многие значения, используя синтаксис `* _` в присваивании: a, * _ = [1, 2, 3, 4, 5] print (a) # Prints: 1 не очень интересно, так как вместо этого вы можете использовать индексирование в списке. Хорошо, когда первое и последнее значения сохраняются в одном присваивании: a, * _, b = [1, 2, 3, 4, 5] print (a, b) # Печатает: 1 5 или извлекает несколько значений одновременно : a, _, b, _, c, * _ = [1, 2, 3, 4, 5, 6] print (a, b, c) # Печать: 1 3 5

  • Аргументы упаковочной функции

    В функциях вы можете определить ряд обязательных аргументов:

     def fun1(arg1, arg2, arg3): 
        return (arg1,arg2,arg3)
    
     

    что сделает функцию вызываемой только тогда, когда заданы три аргумента:

     fun1(1, 2, 3)
    
     

    и вы можете определить аргументы как необязательные, используя значения по умолчанию:

     def fun2(arg1='a', arg2='b', arg3='c'):
        return (arg1,arg2,arg3)
    
     

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

     fun2(1)              → (1,b,c)
    fun2(1, 2)           → (1,2,c)
    fun2(arg2=2, arg3=3) → (a,2,3)
    ...
    
     

    Но вы также можете использовать синтаксис деструктурирующего упаковать аргументы, так что вы можете назначить переменные , используя list или dict .

    Упаковка списка аргументов

    Считайте, что у вас есть список значений

     l = [1,2,3]
    
     

    Вы можете вызвать функцию со списком значений в качестве аргумента , используя * синтаксис:

     fun1(*l)
    # Returns: (1,2,3)
    fun1(*['w', 't', 'f'])
    # Returns: ('w','t','f')
    
     

    Но если вы не предоставите список, длина которого соответствует количеству аргументов:

     fun1(*['oops'])
    # Raises: TypeError: fun1() missing 2 required positional arguments: 'arg2' and 'arg3'
    
     

    Упаковка аргументов ключевых слов

    Теперь вы также можете упаковать аргументы, используя словарь. Вы можете использовать ** оператор сказать Python распаковать dict в качестве значений параметров:

     d = {
      'arg1': 1,
      'arg2': 2,
      'arg3': 3
    }
    fun1(**d)
    # Returns: (1, 2, 3)
    
     

    когда функция имеет только позиционные аргументы (те, у которых нет значений по умолчанию), вам нужно, чтобы словарь содержал все ожидаемые параметры, и не имел никаких дополнительных параметров, иначе вы получите ошибку:

     fun1(**{'arg1':1, 'arg2':2})
    # Raises: TypeError: fun1() missing 1 required positional argument: 'arg3'
    fun1(**{'arg1':1, 'arg2':2, 'arg3':3, 'arg4':4})
    # Raises: TypeError: fun1() got an unexpected keyword argument 'arg4'
    
     

    Для функций, которые имеют необязательные аргументы, вы можете упаковать аргументы как словарь:

     fun2(**d)
    # Returns: (1, 2, 3)
    
     

    Но там вы можете опустить значения, так как они будут заменены значениями по умолчанию:

     fun2(**{'arg2': 2})
    # Returns: ('a', 2, 'c')
    
     

    И так же, как и раньше, вы не можете давать дополнительные значения, которые не являются существующими параметрами:

     fun2(**{'arg1':1, 'arg2':2, 'arg3':3, 'arg4':4})
    # Raises: TypeError: fun2() got an unexpected keyword argument 'arg4'
    
     

    В реальном мире функции могут иметь как позиционные, так и необязательные аргументы, и они работают одинаково:

     def fun3(arg1, arg2='b', arg3='c')
        return (arg1, arg2, arg3)
    
     

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

     fun3(*[1])
    # Returns: (1, 'b', 'c')
    fun3(*[1,2,3])
    # Returns: (1, 2, 3)
    
     

    или только со словарем:

     fun3(**{'arg1':1})
    # Returns: (1, 'b', 'c')
    fun3(**{'arg1':1, 'arg2':2, 'arg3':3})
    # Returns: (1, 2, 3)
    
     

    или вы можете использовать оба в одном вызове:

     fun3(*[1,2], **{'arg3':3})
    # Returns: (1,2,3)
    
     

    Остерегайтесь, однако, что вы не можете предоставить несколько значений для одного и того же аргумента:

     fun3(*[1,2], **{'arg2':42, 'arg3':3})
    # Raises: TypeError: fun3() got multiple values for argument 'arg2' 
  • Распаковка аргументов функции

    Когда вы хотите создать функцию, которая может принимать любое количество аргументов, и не применять позицию или имя аргумента во время «компиляции», это возможно, и вот как:

     def fun1(*args, **kwargs):
        print(args, kwargs)
    
     

    В *args и **kwargs параметры специальные параметры, которые устанавливаются в tuple и dict , соответственно:

     fun1(1,2,3)
    # Prints: (1, 2, 3) {}
    fun1(a=1, b=2, c=3)
    # Prints: () {'a': 1, 'b': 2, 'c': 3}
    fun1('x', 'y', 'z', a=1, b=2, c=3)
    # Prints: ('x', 'y', 'z') {'a': 1, 'b': 2, 'c': 3}
    
     

    Если вы посмотрите на достаточное количество кода Python, вы быстро обнаружите, что он широко используется при передаче аргументов другой функции. Например, если вы хотите расширить класс строки:

     class MyString(str):
        def __init__(self, *args, **kwarg):
            print('Constructing MyString')
            super(MyString, self).__init__(*args, **kwarg) 

Синтаксис

Параметры

Примечания