When using Python, you may find yourself using my_list.pop() to remove the last item from a list, and my_dict.pop('key') to remove an item from a dictionary, among various other objects.

It often feels like pop() is a universal instance method that can be applied to any object. But what exactly is the nature of this pop() method?


1. There is more than one 'pop()'



To put it simply, the pop() of a list and the pop() of a dict are entirely different methods that just happen to share the same name.

  • The list class defines its own pop() method that is tailored for lists.

  • The dict class also defines a pop() method that is suited for dictionaries.

  • The same goes for the set class.

The fact that different objects can have methods with the same name is deeply related to one of Python's object-oriented features known as polymorphism. The name 'pop' merely shares a conventional meaning referring to "removing (pop) an item from a data structure and returning it".


2. Different behaviors of pop() by class

Having the same name does not imply that their functionalities are alike. Each class has implemented pop() in a way that is appropriate for its own data structure.

1. list.pop([index])

  • Functionality: Removes an item at a specific index from the list and returns that item.

  • Feature: If no index is specified, it defaults to -1, which removes the last item. This is consistent with the 'pop' operation in stack data structures.

  • Example:

my_list = ['a', 'b', 'c']

# No index specified (removes the last item 'c')
last_item = my_list.pop()
print(f"Returned value: {last_item}, Remaining list: {my_list}")
# Output: Returned value: c, Remaining list: ['a', 'b']

# Specifying index 0 (removes 'a')
first_item = my_list.pop(0)
print(f"Returned value: {first_item}, Remaining list: {my_list}")
# Output: Returned value: a, Remaining list: ['b']

2. dict.pop(key[, default])

  • Functionality: Removes the item corresponding to the specific key from the dictionary and returns its value.

  • Feature: Unlike list.pop(), you must provide a key instead of an index. If the key does not exist and a default value is provided, that value is returned; if no default is provided, a KeyError is raised.

  • Example:

my_dict = {'apple': 1, 'banana': 2}

# Removing the key 'apple'
item = my_dict.pop('apple')
print(f"Returned value: {item}, Remaining dictionary: {my_dict}")
# Output: Returned value: 1, Remaining dictionary: {'banana': 2}

# Trying a non-existing key ('grape') (returns default value 99)
default_item = my_dict.pop('grape', 99)
print(f"Returned value: {default_item}, Remaining dictionary: {my_dict}")
# Output: Returned value: 99, Remaining dictionary: {'banana': 2}

3. set.pop()

  • Functionality: Removes and returns an arbitrary item from a set.

  • Feature: Sets are unordered collections, so it's impossible to predict which item will be removed. No arguments can be passed to pop().

  • Example:

my_set = {10, 20, 30}

# Removes an arbitrary item (the output is unpredictable)
item = my_set.pop()
print(f"Returned value: {item}, Remaining set: {my_set}")
# Possible output 1: Returned value: 10, Remaining set: {20, 30}
# Possible output 2: Returned value: 20, Remaining set: {10, 30}

3. Why it seems to be "applicable everywhere"



It’s accurate to think of pop() as being similar to an instance method. In fact, pop() is a method that belongs to each object (instance).

Just because it looks like obj.pop() does not mean that pop() is a global function or defined in a parent class of all objects. When Python calls obj.method(), it dynamically checks whether the object obj has an attribute (method) named method.

  • my_list is an instance of the list class, which has pop defined in it.

  • my_dict is an instance of the dict class, which also has pop defined.

That's why both my_list.pop() and my_dict.pop() work.

What happens when you try to call the pop() method on an object that hasn't defined it? As expected, an AttributeError occurs. Let’s take a tuple as an example.

# Tuples cannot change their items, so they don't have a pop() method.
my_tuple = (1, 2, 3)

# AttributeError: 'tuple' object has no attribute 'pop'
my_tuple.pop() 

An infographic illustrating the pop() method in Python across three data structures

Summary

  1. pop() is not a global function or common method in Python.

  2. It is a method that is defined individually by each of the container classes like list, dict, and set.

  3. The reason they share the same name is that they share a conventional meaning of "removing and returning data".

  4. The operational behavior varies across classes; thus, list uses indexes, dict uses keys, and set removes items arbitrarily.