Как распаковать список в python
Перейти к содержимому

Как распаковать список в python

  • автор:

Как распаковать список в python

Распаковка ( unpacking , также называемая Деструктуризация ) представляет разложение коллекции (кортежа, списка и т.д.) на отдельные значения.

Так, как и многие языки программирования, Python поддерживает концепцию множественного присваивания. Например:

x, y = 1, 2 print(x) # 1 print(y) # 2

В данном случае присваивем значения сразу двум переменным. Присвоение идет по позиции: переменная x получает значение 1, а переменная y — значени 2.

Данный пример в действительности уже представляет деструктуризацию или распаковку. Значения 1, 2 фактически являются кортежом, поскольку именно запятые между значениями говорят о том, что это кортеж. И мы также могли бы написать следующим образом:

x, y = (1, 2) print(x) # 1 print(y) # 2

В любом случае мы имеем дело с деструктуризацией, когда первый элемент кортежа передается первой переменной, второй элемент — второй переменной и так далее. То есть разложение идет по позиции.

Подобным образом можно разложить другие кортежи, например:

name, age, company = ("Tom", 38, "Google") print(name) # Tom print(age) # 38 print(company) # Google

Только кортежами мы не ограничены и можем «распаковывать» и другие коллекции, например, списки:

people = ["Tom", "Bob", "Sam"] first, second, third = people print(first) # Tom print(second) # Bob print(third) # Sam

При разложении словаря переменные получают ключи словаря:

dictionary = r, b, g = dictionary print(r) # red print(b) # blue print(g) # green # получаем значение по ключу print(dictionary[g]) # зеленый

Деструктуризация в циклах

Циклы в Python позволяют разложить коллекции на отдельные составляющие:

people = [ ("Tom", 38, "Google"), ("Bob", 42, "Microsoft"), ("Sam", 29, "JetBrains") ] for name, age, company in people: print(f"Name: , Age: , Company: ")

Здесь мы перебираем список кортежей people. Каждый кортеж состоит из трех элементов, соответственно при переборе мы можем их передать в переменные name, age и company.

Другой пример — функция enumerate() . Она принимает в качестве параметра коллекцию, создает для каждого элемента кортеж и возвращает набор из подобных кортежей. Каждый кортеж содержит индекс, который увеличивается с каждой итерацией:

people = ["Tom", "Bob", "Sam"] for index, name in enumerate(people): print(f".") # результат # 0.Tom # 1.Bob # 2.Sam

Игнорирование значений

Если какой-то элемент коллекции не нужен, то обычно для него определяется переменная с именем _ (прочерк):

person =("Tom", 38, "Google") name, _, company = person print(name) # Tom print(company) # Google

Здесь нам не важен второй элемент кортежа, поэтому для него определяем переменную _. Хотя в реальности _ — такое же действительное имя, как name и company:

name, _, company = person print(_) # 38

Упаковка значений и оператор *

Оператор * упаковывает значение в коллекцию. Например:

num1=1 num2=2 num3=3 *numbers,=num1,num2,num3 print(numbers) #[1, 2, 3]

Здесь мы упаковываем значения из кортежа (num1,num2,num3) в список numbers. Причем, чтобы получить список, после numbers указывается запятая.

Как правило, упаковка применяется для сбора значений, которые остались после присвоения результатов деструктуризации. Например:

head, *tail = [1, 2, 3, 4, 5] print(head) # 1 print(tail) # [2, 3, 4, 5]

Здесь переменная head в соответствии с позицией получае первый элемент списка. Все остальные элементы передаются в переменную tail . Таким образом, переменная tail будет представлять список из оставшихся элементов.

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

*head, tail = [1, 2, 3, 4, 5] print(head) # [1, 2, 3, 4] print(tail) # 5

Или элементы по середине, кроме первого и последнего:

head, *middle, tail = [1, 2, 3, 4, 5] print(head) # 1 print(middle) # [2, 3, 4] print(tail) # 5

Или все кроме первого и второго:

first, second, *other = [1, 2, 3, 4, 5] print(first) # 1 print(second) # 2 print(other) # [3, 4, 5]

Вообщем, таким образом мы можем получать различные комбинации элементов коллекции. Причем не только списков, но и кортежей, словарей и других коллекций.

Другой пример — нам надо получить только первый, третий и последний элемент, а остальные элементы нам не нужны. В общем случае мы должны предоставить переменные для всех элементов коллекции. Однако если коллекция имеет 100 элементов, а нам нужно только три, не будем же мы определять все сто переменных. И в этом случае опять же можно применить упаковку:

first, _, third, *_, last = [1, 2, 3, 4, 5, 6, 7, 8] print(first) # 1 print(third) # 3 print(last) # 8

Также можно получить ключи словаря:

red, *other, green = print(red) # red print(green) # green print(other) # ['blue', 'yellow']

Распаковка и операторы * и **

Оператор * вместе с оператором ** также может применяться для распаковки значений. Оператор * используется для распаковки кортежей, списков, строк, множеств, а оператор ** — для распаковки словарей. Особенно это может быть полезно, когда на основе одних коллекций создаются другие. Например, распаковка кортежей и списков:

nums1 = [1, 2, 3] nums2 = (4, 5, 6) # распаковываем список nums1 и кортеж nums2 nums3 = [*nums1, *nums2] print(nums3) # [1, 2, 3, 4, 5, 6]

Здесь распаковывем значения из списка nums1 и кортежа nums2 и помещаем их в список nums3.

Подобным образом раскладываются словари, только применяется оператор ** :

dictionary1 = dictionary2 = # распаковываем словари dictionary3 = <**dictionary1, **dictionary2>print(dictionary3) #

Как правильно распаковать в список?

Да, это понятно. Я хотелось методом распаковки через * увидеть. Например: first, *mylist = stroka будет всё, кроме первого символа, вот и подумалось, может как то скобками можно изголица, чтобы всю строку засунуть в массив.

23 дек 2016 в 1:36

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Собственно, если внимательно прочитать сообщение об ошибке при использовании выражения

>>> s = "string" >>> *l = s *l = s ^ SyntaxError: starred assignment target must be in a list or tuple 

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

>>> *l, = s >>> l ['s', 't', 'r', 'i', 'n', 'g'] >>> [*l] = s >>> l ['s', 't', 'r', 'i', 'n', 'g'] 

Так как в Python во многих случаях можно создавать кортеж, используя только запятую, то *l, = s просто является краткой формой записи выражения (*l, ) = s

Операторы упаковки и распаковки — Python: Функции

В Python операторы * и ** используются, чтобы упаковывать и распаковывать итерабельные объекты и словари. Эти операторы обеспечивают гибкий способ обработки аргументов функций и позволяют писать функции, которые могут принимать переменное количество аргументов. В этом уроке мы узнаем, как пользоваться ими.

Оператор *

Оператор * используется для упаковки и распаковки итерируемых объектов, таких как списки или кортежи. При использовании перед итерируемым объектом, во время вызова функции, оператор * распаковывает его. Элементы итерируемого объекта передаются в качестве аргумента функции:

def sum_of_values(a, b, c): return a + b + c values = [1, 2, 3] result = sum_of_values(*values) print(result) # 6 

В этом примере оператор * используется, чтобы распаковывать список значений и передавать его элементы в качестве аргументов функции sum_of_values .

Также оператор * можно использовать, чтобы распаковывать итерабельные переменные. Это позволяет присваивать их отдельным переменным:

my_list = [1, 2, 3, 4] a, b, *c = my_list print(a, b, c) # 1 2 [3, 4] 

В этом примере оператор * используется не во время вызова функции, а для распаковки списка my_list в отдельные переменные a , b и c .

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

my_list = [1, 2, 3] new_list = [*my_list, 4, 5, 6] print(new_list) # [1, 2, 3, 4, 5, 6] my_tuple = (1, 2, 3) new_tuple = (*my_tuple, 4, 5, 6) print(new_tuple) # (1, 2, 3, 4, 5, 6) 

В этих примерах оператор * используется для распаковки итераций my_list и my_tuple в новые списки и кортежи с добавлением дополнительных значений.

Оператор **

Оператор ** используется для упаковки и распаковки словарей. При использовании перед словарем во время вызова функции оператор ** упаковывает пары ключ-значение словаря в аргументы ключевых слов, которые могут быть переданы в функцию:

def print_details(name, age): print(f"Name: name>") print(f"Age: age>") details = "name": "John", "age": 30> print_details(**details) # Name: John # Age: 30 

В этом примере оператор ** используется для распаковки словаря details и передачи его пар ключ-значение в качестве аргументов ключевых слов в функцию print_details .

Оператор ** также можно использовать для создания словаря из последовательности пар ключ-значение:

dict1 = "a": 1, "b": 2> dict2 = "c": 3, "d": 4> combined_dict = **dict1, **dict2> print(combined_dict) # 

В приведенном выше коде определяются два словаря dict1 и dict2 . А оператор ** используется для распаковки их пар ключ-значение и объединения в один словарь combined_dict .

Если ключи дублируются, то значение из второго словаря перезапишет значение из первого словаря.

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов

Наши выпускники работают в компаниях:

Распаковка переменных#

Распаковка переменных — это специальный синтаксис, который позволяет присваивать переменным элементы итерируемого объекта.

Достаточно часто этот функционал встречается под именем tuple unpacking, но распаковка работает на любом итерируемом объекте, не только с кортежами

Пример распаковки переменных:

In [1]: interface = ['FastEthernet0/1', '10.1.1.1', 'up', 'up'] In [2]: intf, ip, status, protocol = interface In [3]: intf Out[3]: 'FastEthernet0/1' In [4]: ip Out[4]: '10.1.1.1' 

Такой вариант намного удобней использовать, чем использование индексов:

In [5]: intf, ip, status, protocol = interface[0], interface[1], interface[2], interface[3] 

При распаковке переменных каждый элемент списка попадает в соответствующую переменную. Важно учитывать, что переменных слева должно быть ровно столько, сколько элементов в списке.

Если переменных больше или меньше, возникнет исключение:

In [6]: intf, ip, status = interface ------------------------------------------------------------ ValueError Traceback (most recent call last) ipython-input-11-a304c4372b1a> in module>() ----> 1 intf, ip, status = interface ValueError: too many values to unpack (expected 3) In [7]: intf, ip, status, protocol, other = interface ------------------------------------------------------------ ValueError Traceback (most recent call last) ipython-input-12-ac93e78b978c> in module>() ----> 1 intf, ip, status, protocol, other = interface ValueError: not enough values to unpack (expected 5, got 4) 

Замена ненужных элементов _ #

Часто из всех элементов итерируемого объекта нужны только некоторые. При этом синтаксис распаковки требует указать ровно столько переменных, сколько элементов в итерируемом объекте.

Если, например, из строки line надо получить только VLAN, MAC и интерфейс, надо все равно указать переменную для типа записи:

In [8]: line = '100 01bb.c580.7000 DYNAMIC Gi0/1' In [9]: vlan, mac, item_type, intf = line.split() In [10]: vlan Out[10]: '100' In [11]: intf Out[11]: 'Gi0/1' 

Если тип записи не нужен в дальнейшем, можно заменить переменную item_type нижним подчеркиванием:

In [12]: vlan, mac, _, intf = line.split() 

Таким образом явно указывается то, что этот элемент не нужен.

Нижнее подчеркивание можно использовать и несколько раз:

In [13]: dhcp = '00:09:BB:3D:D6:58 10.1.10.2 86250 dhcp-snooping 10 FastEthernet0/1' In [14]: mac, ip, _, _, vlan, intf = dhcp.split() In [15]: mac Out[15]: '00:09:BB:3D:D6:58' In [16]: vlan Out[16]: '10' 

Использование * #

Распаковка переменных поддерживает специальный синтаксис, который позволяет распаковывать несколько элементов в один. Если поставить * перед именем переменной, в нее запишутся все элементы, кроме тех, что присвоены явно.

Например, так можно получить первый элемент в переменную first, а остальные в rest:

In [18]: vlans = [10, 11, 13, 30] In [19]: first, *rest = vlans In [20]: first Out[20]: 10 In [21]: rest Out[21]: [11, 13, 30] 

При этом переменная со звездочкой всегда будет содержать список:

In [22]: vlans = (10, 11, 13, 30) In [22]: first, *rest = vlans In [23]: first Out[23]: 10 In [24]: rest Out[24]: [11, 13, 30] 

Если элемент всего один, распаковка все равно отработает:

In [25]: first, *rest = vlans In [26]: first Out[26]: 55 In [27]: rest Out[27]: [] 

Такая переменная со звездочкой в выражении распаковки может быть только одна.

In [28]: vlans = (10, 11, 13, 30) In [29]: first, *rest, *others = vlans File "", line 1 first, *rest, *others = vlans ^ SyntaxError: two starred expressions in assignment 

Такая переменная может находиться не только в конце выражения:

In [30]: vlans = (10, 11, 13, 30) In [31]: *rest, last = vlans In [32]: rest Out[32]: [10, 11, 13] In [33]: last Out[33]: 30 

Таким образом можно указать, что нужен первый, второй и последний элемент:

In [34]: cdp = 'SW1 Eth 0/0 140 S I WS-C3750- Eth 0/1' In [35]: name, l_intf, *other, r_intf = cdp.split() In [36]: name Out[36]: 'SW1' In [37]: l_intf Out[37]: 'Eth' In [38]: r_intf Out[38]: '0/1' 

Примеры распаковки#

Распаковка итерируемых объектов#

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

In [39]: first, *rest = range(1, 6) In [40]: first Out[40]: 1 In [41]: rest Out[41]: [2, 3, 4, 5] 
In [42]: a = [1, 2, 3, 4, 5] In [43]: b = [100, 200, 300, 400, 500] In [44]: zip(a, b) Out[44]: zip at 0xb4df4fac> In [45]: list(zip(a, b)) Out[45]: [(1, 100), (2, 200), (3, 300), (4, 400), (5, 500)] In [46]: first, *rest, last = zip(a, b) In [47]: first Out[47]: (1, 100) In [48]: rest Out[48]: [(2, 200), (3, 300), (4, 400)] In [49]: last Out[49]: (5, 500) 

Пример распаковки в цикле for#

Пример цикла, который проходится по ключам:

In [50]: access_template = ['switchport mode access', . : 'switchport access vlan', . : 'spanning-tree portfast', . : 'spanning-tree bpduguard enable'] . : In [51]: access = '0/12': 10, '0/14': 11, '0/16': 17> In [52]: for intf in access: . : print(f'interface FastEthernet intf>') . : for command in access_template: . : if command.endswith('access vlan'): . : print(' <> <>'.format(command, access[intf])) . : else: . : print(' <>'.format(command)) . : interface FastEthernet0/12 switchport mode access switchport access vlan 10 spanning-tree portfast spanning-tree bpduguard enable interface FastEthernet0/14 switchport mode access switchport access vlan 11 spanning-tree portfast spanning-tree bpduguard enable interface FastEthernet0/16 switchport mode access switchport access vlan 17 spanning-tree portfast spanning-tree bpduguard enable 

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

In [53]: for intf, vlan in access.items(): . : print(f'interface FastEthernet intf>') . : for command in access_template: . : if command.endswith('access vlan'): . : print(' <> <>'.format(command, vlan)) . : else: . : print(' <>'.format(command)) . : 

Пример распаковки элементов списка в цикле:

In [54]: table Out[54]: [['100', 'a1b2.ac10.7000', 'DYNAMIC', 'Gi0/1'], ['200', 'a0d4.cb20.7000', 'DYNAMIC', 'Gi0/2'], ['300', 'acb4.cd30.7000', 'DYNAMIC', 'Gi0/3'], ['100', 'a2bb.ec40.7000', 'DYNAMIC', 'Gi0/4'], ['500', 'aa4b.c550.7000', 'DYNAMIC', 'Gi0/5'], ['200', 'a1bb.1c60.7000', 'DYNAMIC', 'Gi0/6'], ['300', 'aa0b.cc70.7000', 'DYNAMIC', 'Gi0/7']] In [55]: for line in table: . : vlan, mac, _, intf = line . : print(vlan, mac, intf) . : 100 a1b2.ac10.7000 Gi0/1 200 a0d4.cb20.7000 Gi0/2 300 acb4.cd30.7000 Gi0/3 100 a2bb.ec40.7000 Gi0/4 500 aa4b.c550.7000 Gi0/5 200 a1bb.1c60.7000 Gi0/6 300 aa0b.cc70.7000 Gi0/7 

Но еще лучше сделать так:

In [56]: for vlan, mac, _, intf in table: . : print(vlan, mac, intf) . : 100 a1b2.ac10.7000 Gi0/1 200 a0d4.cb20.7000 Gi0/2 300 acb4.cd30.7000 Gi0/3 100 a2bb.ec40.7000 Gi0/4 500 aa4b.c550.7000 Gi0/5 200 a1bb.1c60.7000 Gi0/6 300 aa0b.cc70.7000 Gi0/7 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *