Распаковка аргументов для передачи в функцию Python
Бывают ситуации, когда для функции, требующей отдельных позиционных аргументов, значения этих аргументов уже находятся в списке или кортеже, и для вызова функции должны быть распакованы.
Например, встроенная range() функция ожидает отдельные аргументы start и stop . Если они не доступны отдельно, то можно распаковать аргументы из списка list или кортежа tuple , вызвав функцию с переменной этого списка/кортежа, а впереди нее поставить символ одной звездочки * :
# обычный вызов с отдельными аргументами >>> list(range(3, 6)) # [3, 4, 5] >>> args = [3, 6] # вызов с аргументами, распакованными из списка >>> list(range(*args)) # [3, 4, 5]
Таким же образом, из словаря dict в функцию можно передать ключевые аргументы, только в этом случае, перед переменной словаря ставится два символов звездочки ** :
>>> def parrot(voltage, state='a stiff', action='voom'): . print("-- This parrot wouldn't", action, end=' ') . print("if you put", voltage, "volts through it.", end=' ') . print("E's", state, "!") . >>> d = "voltage": "four million", "state": "bleedin' demised", "action": "VOOM"> >>> parrot(**d) # -- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demis
- символом * — распаковывают последовательности в качестве элементов которых одно значение (списки, кортежи, множества)
- два символа ** — распаковывают последовательности в качестве элементов которых имеется ключ и значение (словари)
Примеры распаковки списков и словарей с аргументами для функции:
date_inf = 'year': "2020", 'month': "12", 'day': "06"> f_name = " - - .txt".format(**date_inf) print(f_name) # 2020-12-06.txt fruits = ['lemon', 'orange', 'banana', 'tomato'] print(*fruits) # lemon orange banana tomato
Распаковку аргументов можно использовать несколько раз в функции:
date_info = 'year': "2020", 'month': "01", 'day': "01"> track_info = 'artist': "Beethoven", 'title': 'Symphony No 5'> filename = " - - - - .txt".format(**date_info, **track_info) print(filename) # 2020-01-01-Beethoven-Symphony No 5.txt
fruits = ['lemon', 'orange', 'banana', 'tomato'] first, second, *orher = fruits print(orher) # ['banana', 'tomato'] first, *orher = fruits print(orher) # ['orange', 'banana', 'tomato'] first, *middle, last = fruits print(middle) # ['orange', 'banana']
- КРАТКИЙ ОБЗОР МАТЕРИАЛА.
- Функции это объекты
- Функции могут иметь атрибуты
- Функции могут храниться в структурах данных
- Функции могут быть вложенными
- Передача функции в качестве аргумента другой функции
- Область видимости переменных функции
- Операторы global и nonlocal
- Параметры (аргументы) функции
- Ключевые аргументы в определении функции Python
- Значение аргумента по умолчанию в функциях Python
- Варианты передачи аргументов в функцию Python
- Переменные аргументов *args и **kwargs в функции Python
- Распаковка аргументов для передачи в функцию Python
- Как оцениваются аргументы при вызове функции?
- Строгие правила передачи аргументов в функцию Python
- Инструкция return
- Анонимные функции (lambda-выражения)
- Строки документации в функциях 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) #
Операторы упаковки и распаковки — 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 студентов
Наши выпускники работают в компаниях:
BreakingCode
Красивый Питон — часть 3. Распаковка в Python.
Перед вами очередная статья об идиомах Python. Этот пост расскажет о такой штуке, как распаковка в Python. Другими словами, о разделении последовательностей (списков, кортежей) в другие переменные. Для этих нужд есть удобные и элегантные методы использования.
Как производится распаковка в Python?
Распаковка работает с различными типами последовательностей, и выделят содержимое последовательности в другие элементы. В Питоне есть несколько типов последовательности, для которых определено множество встроенных функций. Один из типов последовательности в Python — списки.
Распаковка последовательностей в Python
Сначала посмотрим на базовый прием распаковки. Синтаксис очень простой и интуитивно понятный:
#Как распаковать? user = [0, 180, 75] user_id, height, weight = user name = ("Jamal", "Moir") f_name, l_name = name
Как видите, все что нужно сделать — это указать переменные, которым будут присвоены элементы последовательности. Имейте ввиду, что для этого нужно знать, сколько элементов содержится в той или иной последовательности.
Перестановка переменных Python
Это маленький бриллиант в Питоне. Однажды вам понадобиться поменять местами переменные — обязательно используйте эту идиому!
#Не переставляйте переменные так: temp = a a = b b = temp #Используйте такую штуку! a, b = b, a
Добавить здесь больше нечего. Просто, легко, блестяще.
Распаковка с enumerate() в Python
Нечто подобное уже было в посте про циклы, но пожалуй стоит отметить эту идиому еще раз, теперь в контексте распаковки.
#Распаковка с использованием enumerate() for i, val in enumerate(primes, 1): print(" is prime number .".format(prime=val, n=i))
Как было рассказано ранее, enumerate создает кортеж размером 2. В примере выше распаковка использована для доступа к отдельным частям созданного кортежа — это позволило использовать удобочитаемые имена в пределах цикла.
Расширенные возможности распаковки в Python
Новое в Python 3 — «расширенная распаковка». Это дополнение, которое позволяет указать переменную, которая будет иметь список значений и распаковать последовательность в нее. В коде ниже содержание переменных показано в комментарии после строки кода.
#Как использовать расширенную распаковку a, *b, c = range(10) #a = 0, b = [1, 2, 3, 4, 5, 6, 7, 8], c = 9 d, *e = range(10) #d = 0, e = [1, 2, 3, 4, 5, 6, 7, 8, 9]
Переменная, перед которой стоит звездочка будет содержать список, если распаковываемых значений больше, чем указано переменных. Это позволяет вам распаковать последовательности, длина которых заранее неизвестна.
Использование анонимных переменных при распаковке
Если нужно распаковать последовательность, но при этом не использовать все значения — используйте одноразовую переменную.
#временная переменная user = ["Breaking", "Coder", "07778889999"] f_name, __, phone_no = user print("Hello , your phone number is .".format(name=f_name, no=phone_no))
В примере выше используется двойное подчеркивание. Одинарное тоже можно использовать, ну при этом могут возникать проблемы. Так что лучше не рисковать.
Надеюсь, вы узнали в этой статье что-то новое для себя. От себя могу сказать лишь, что знакомство с идиомами Python приносит все больше удовольствия от программирования.
Спасибо Jamal Moir за замечательные советы.
Похожие посты:
- Красивый Питон — часть 1. Правильные циклы в Python.
- Красивый Питон — часть 2. Cписки в Python.
- Красивый Питон — часть 4. Словари в Python.
- Красивый Питон — часть 5. Другие идиомы Python.
- Как сделать красивый сайт?
