Операторы * и ** для упаковки и распаковки коллекций

Опубликован: 02.09.2023 115

Одним из мощных инструментов в Python являются префиксные операторы * и ** упаковки и распаковки итерируемых объектов, таких как списки, кортежи, множества, словари.

Python поддерживает концепцию множественного присваивания.

Это означает, что одним оператором = можно присваивать значения сразу нескольким переменным: a, b, c = 1, 2, 3. Присвоение осуществляется по позиции переменной, главное, чтобы количество элементов слева от оператора = было равно количеству элементов справа.

По сути, такая операция уже является распаковкой кортежа (1, 2, 3) по позиции элементов, когда первый элемент кортежа передается первой переменной, второй элемент - второй переменной и так далее.

# пример распаковки списка
people = ["Дмитрий", "Александр", "Михаил"]
first, second, third = people
print(first)      # Дмитрий
print(second)     # Александр
print(third)      # Михаил

# пример распаковки кортежа
name, age, company = ("Михаил", 35, "Yandex")
print(name)         # Михаил
print(age)          # 35
print(company)      # Yandex

# при распаковке словаря переменным присваиваются значения его ключей
dictionary = {"red": "красный", "black": "черный", "green": "зеленый"}
r, b, g = dictionary
print(r)    # red
print(b)    # black
print(g)    # green

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

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

Оператор *

Оператор * используется для упаковки и распаковки итерируемых объектов (контейнерного типа), таких как списки, кортежи, множества.

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

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 в новые списки и кортежи с добавлением дополнительных значений.

Еще один удивительный трюк с оператором * - распечатывание в одну строку элементов последовательности без использования цикла for:

my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]
my_tuple = (2, 4, 6, 8, 10, 12)
my_set = {5, 10, 15, 20, 25, 30}

print(*my_list)   # печать в одну строку элементов списка
1 2 3 4 5 6 7 8 9

print(*my_tuple)    # печать в одну строку элементов кортежа
2 4 6 8 10 12

print(*my_set)    # печать в одну строку элементов множества
20 5 25 10 30 15

Оператор **

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

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

Оператор ** также можно использовать для распаковки словарей dict1 и dict2 при создании нового объединенного словаря combined_dict из последовательности пар ключ-значение:

dict1 = {"a": 1, "b": 2}
dict2 = {"c": 3, "d": 4}

combined_dict = {**dict1, **dict2}

print(combined_dict)
{"a": 1, "b": 2, "c": 3, "d": 4}

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

Похожие посты

Оценка основных статистических метрик набора данных в Python

Область эффективного использования lambda функции в Python

Логические выражения if ... else в Pythonic стиле

Способы удаления лишних пробелов в строке

Комментариев нет.