Супер-звезда Python. 5 способов использования оператора *.
Символ звездочка (
*
) или астериск в Python - это многофункциональный оператор, который служит одновременно как оператор умножения или возведения в степень, а также для работы с аргументами в функциях.
Новичкам достаточно знать его основное применение в качестве оператора умножения. Однако, если Вы собираетесь стать экспертом по Python, то нужно углубить свои знания! Пришло время узнать, насколько полезна и мощна “звездочка” в Python.
В этой статье мы рассмотрим 5 способов использования оператора *
с описанием и примерами, от элементарных к более сложным.
Способ 1: Умножить или возвести в степень
Самое очевидное - использовать звездочки как математические операторы:
*
- операция умножения.**
- операция возведения в степень.
2*3
# 6
2**3
# 9
Способ 2: Любое количество аргументов функции
Функция не обязательно должна получать фиксированное количество аргументов.
Предположим, что Вы заранее не знаете, сколько аргументов будет передано. Здесь «звездочки» могут прийти к Вам на помощь!
def print_genius(*names):
print(type(names))
for n in names:
print(n)
print_genius('Elon Mask', 'Mark Zuckerberg ', 'Yang Zhou')
# class 'tuple'
# Elon Mask
# Mark Zuckerberg
# Yang Zhou
def top_genius(**names):
print(type(names))
for k, v in names.items():
print(k, v)
top_genius(Top1="Elon Mask", Top2="Mark Zuckerberg", Top3="Yang Zhou")
# class 'dict'
# Top1 Elon Mask
# Top2 Mark Zuckerberg
# Top3 Yang Zhou
Как показано в приведенном выше примере, при определении функции мы можем определить параметр с префиксом из одной или двух звездочек для передачи неограниченного количества аргументов.
- Параметр с префиксом
*
может записывать любое количество позиционных аргументов вtuple
из аргументов - Параметр с префиксом
**
может записывать любое количество именованных аргументов и составить из них словарьdict
Если число аргументов функции не может быть определено заранее, то мы определяем ее следующим образом:
def func(*args, **kwargs):
pass
Вообще говоря, вместо
args
иkwargs
может стоять все, что угодно - это просто общепринятое соглашение. Можете написатьtea
иcoffee
. Но понятней от этого не станет :)
Способ 3: Контроль за именованными аргументами
Еще одно полезное использование звездочек - заставить функцию принимать только именованные аргументы.
Например,
def genius(*, first_name, last_name):
print(first_name, last_name)
genius('Yang','Zhou')
# TypeError: genius() takes 0 positional arguments but 2 were given
genius(first_name='Yang', last_name='Zhou')
# Yang Zhou
Как показано в приведенном выше примере, одна звездочка *
вводит ограничение: все последующие аргументы должны быть именованными.
Если нам нужно ввести ограничение на несколько именованных аргументов и оставить некоторые аргументы позиционными, то нужно просто поставить позиционные аргументы перед звездочкой:
def genius(age, *, first_name, last_name):
print(first_name, last_name, 'is', age)
genius(28, first_name='Yang', last_name='Zhou')
# Yang Zhou is 28
В данном примере, если бы Вы ввели ‘Yang’ без ключевого слова first_name
, то Вы получили бы ошибку.
Ситуация 4: Распаковка объектов
Мы можем использовать звездочки для распаковки кортежей, списков, словарей и других итерируемых объектов, что сделает наши программы понятными и элегантными.
Например, если мы собираемся объединить элементы разных итерируемых объектов, например, один список, один кортеж и один набор в новый список, что нам делать?
Очевидно, мы можем использовать циклы for
для перебора всех элементов и добавления их в новый список один за другим:
A = [1, 2, 3]
B = (4, 5, 6)
C = {7, 8, 9}
L = []
for a in A:
L.append(a)
for b in B:
L.append(b)
for c in C:
L.append(c)
print(L)
# [1, 2, 3, 4, 5, 6, 8, 9, 7]
Таким образом можно выполнить нашу миссию, но код выглядит таким длинным и не очень оптимизированным. Лучший метод - использовать генератор списков:
A = [1, 2, 3]
B = (4, 5, 6)
C = {7, 8, 9}
L = [a for a in A] + [b for b in B] + [c for c in C]
print(L)
# [1, 2, 3, 4, 5, 6, 8, 9, 7]
Мы сократили три цикла for до одной строки. Это уже хороший код, но способ не самый простой! Можно еще красивей.
Пора посмотреть, насколько красивы в данной ситуации звездочки :)
A = [1, 2, 3]
B = (4, 5, 6)
C = {7, 8, 9}
L = [*A, *B, *C]
print(L)
# [1, 2, 3, 4, 5, 6, 8, 9, 7]
Как показано в примере выше, мы можем использовать звездочку в качестве префикса объектов для распаковки их элементов. Кстати, если мы используем *
в качестве префикса к словарю, то будут распакованы его ключи. Если мы используем двойные звездочки **
в качестве префикса, то будут распакованы его значения. Однако, мы должны использовать ключи для получения распакованных значений. Из-за этого неудобства не принято извлекать элементы из словаря помощью звездочек.
D = {'first': 1, 'second': 2, 'third': 3}
print(*D)
# first second third
# print(**D)
# TypeError: 'first' is an invalid keyword argument for print()
print('{first},{second},{third}'.format(**D)) # 1,2,3
Ситуация 5: Множественное присваивание
Этот синтаксис распаковки был введен в PEP 3132, чтобы сделать наш код более элегантным.
Этот PEP позволяет указать «всеобъемлющее» имя, в который будет помещен весь список элементов, которым не присвоено «обычное» имя.
Простой пример:
L = [1, 2, 3, 4, 5, 6, 7, 8]
a, *b = L
print(a)
# 1
print(b)
# [2, 3, 4, 5, 6, 7, 8]
Всё понятно?
Потренируйтесь использовать*
в Python - попробуйте решить нашу задачу!Эпилог
Звездочка - один из наиболее часто используемых операторов в программировании на любом языке. Однако, в Python много интересных конструкций, которыми можно и нужно пользоваться. Это покажет Ваш профессионализм, а также сделает Ваш код более читаемым и качественным.