При использовании Python вы обнаружите, что используете my_list.pop() для удаления последнего элемента списка и my_dict.pop('key') для удаления элемента из словаря, и т.д.
Это может создать впечатление, что pop() - это универсальный метод экземпляра, который можно использовать с любым объектом. Так в чем же заключается суть этого метода pop()?
1. 'pop()' не единственный
Если сказать кратко, pop() для list и pop() для dict - это совершенно разные методы, хоть и имеют одинаковое название.
-
listкласс определяет собственный методpop(), подходящий для списков. -
Класс
dictтакже определяет свой собственный методpop(), подходящий для словарей. -
Класс
setделает то же самое.
То, что разные объекты имеют методы с одинаковыми именами, связано с особенностью объектно-ориентированного программирования в Python, называемой полиморфизмом (Polymorphism). Название 'pop' подразумевает "извлечение элемента из структуры данных и его возврат" и имеет общепринятое значение.
2. Разные способы работы pop() в зависимости от класса
Однако наличие одинакового названия не означает, что их поведение будет одинаковым. Каждый класс реализует pop() согласно своей структуре данных.
1. list.pop([index])
-
Действие: удаляет элемент с указанным индексом из списка и возвращает его.
-
Особенность: Если индекс не указан, применяется значение по умолчанию
-1, что приводит к удалению последнего элемента. Это аналогично операции 'pop' в структуре данных Stack. -
Пример:
my_list = ['a', 'b', 'c']
# Индекс не указан (удаление последнего элемента 'c')
last_item = my_list.pop()
print(f"Возвращенное значение: {last_item}, оставшийся список: {my_list}")
# Вывод: Возвращенное значение: c, оставшийся список: ['a', 'b']
# Указан индекс 0 ('a' удаляется)
first_item = my_list.pop(0)
print(f"Возвращенное значение: {first_item}, оставшийся список: {my_list}")
# Вывод: Возвращенное значение: a, оставшийся список: ['b']
2. dict.pop(key[, default])
-
Действие: удаляет элемент (ключ-значение) из словаря по указанному ключу и возвращает его значение.
-
Особенность: В отличие от
list.pop(), необходимо передать ключ, а не индекс. Если ключа нет и передано значениеdefault, возвращается это значение, если значениеdefaultне передано, возникает ошибкаKeyError. -
Пример:
my_dict = {'apple': 1, 'banana': 2}
# Удаление ключа 'apple'
item = my_dict.pop('apple')
print(f"Возвращенное значение: {item}, оставшийся словарь: {my_dict}")
# Вывод: Возвращенное значение: 1, оставшийся словарь: {'banana': 2}
# Попытка удалить несуществующий ключ ('grape') (возвращает значение по умолчанию 99)
default_item = my_dict.pop('grape', 99)
print(f"Возвращенное значение: {default_item}, оставшийся словарь: {my_dict}")
# Вывод: Возвращенное значение: 99, оставшийся словарь: {'banana': 2}
3. set.pop()
-
Действие: удаляет случайный элемент из множества (set) и возвращает его.
-
Особенность: Поскольку множество является неупорядоченной структурой данных, невозможно предсказать, какой элемент будет удален.
pop()вызывается без передачи аргументов. -
Пример:
my_set = {10, 20, 30}
# Удаление случайного элемента (неизвестно, какой будет результат)
item = my_set.pop()
print(f"Возвращенное значение: {item}, оставшееся множество: {my_set}")
# Возможный вывод 1: Возвращенное значение: 10, оставшееся множество: {20, 30}
# Возможный вывод 2: Возвращенное значение: 20, оставшееся множество: {10, 30}
3. Причина, по которой кажется, что он «повсюду»
Мы можем думать о pop() как о методе экземпляра. Это верно. pop() фактически является методом, принадлежащим каждому объекту (экземпляру).
Хотя это и выглядит как obj.pop(), pop() не является глобальной функцией или методом, определенным в родительском классе всех объектов. Когда Python вызывает obj.method(), он динамически проверяет, есть ли у объекта obj свойство (метод) с именем method.
-
my_listявляется экземпляром классаlist, и в классеlistопределен методpop. -
my_dictявляется экземпляром классаdict, и в классеdictтакже определен методpop.
Поэтому как my_list.pop(), так и my_dict.pop() работают.
Что произойдет, если попытаться вызвать метод pop() на объекте, который его не определяет? Как и ожидалось, возникнет ошибка AttributeError. Рассмотрим пример с кортежем.
# Кортеж (tuple) не может изменяться, поэтому у него нет метода pop().
my_tuple = (1, 2, 3)
# AttributeError: 'tuple' object has no attribute 'pop'
my_tuple.pop()

Резюме
-
pop()не является глобальной функцией или общим методом Python. -
list,dict,setи т. д. - это методы, определенные отдельно для каждого контейнера. -
Причина, по которой они имеют одинаковое название, заключается в том, что они разделяют традиционное значение "извлечь и вернуть данные".
-
Поскольку их поведение различно,
listиспользует индексы,dict- ключи, аset- случайные элементы.
Комментариев нет.