Yes, it is O(1) to pop the last element of a Python list, and O(N) to pop an arbitrary element (since the whole rest of the list has to be shifted).
Here's a great article on how Python lists are stored and manipulated: An Introduction to Python Lists.
Answer from Dan Lenski on Stack OverflowYes, it is O(1) to pop the last element of a Python list, and O(N) to pop an arbitrary element (since the whole rest of the list has to be shifted).
Here's a great article on how Python lists are stored and manipulated: An Introduction to Python Lists.
Pop() for the last element ought to be O(1) since you only need to return the element referred to by the last element in the array and update the index of the last element. I would expect pop() for an arbitrary element to be O(N) and require on average N/2 operations since you would need to move any elements beyond the element you are removing one position up in the array of pointers.
algorithm - Why is the big O of pop() different from pop(0) in python - Stack Overflow
I was surprised at how slow list.pop() is! And list.remove() is even many times slower
If time complexity of pop (first item) is O(n) and the time complexity for a set slice is O(k), why is my slicing function so slow?
Is popleft() faster than pop(0) ?
Yes. list.pop(0) is O(n), and deque.popleft() is O(1).
What does list.pop() do in Python?
What does list.pop() return?
Why is pop(0) slow on large lists?
Python's list implementation uses a dynamically resized C array under the hood, removing elements usually requires you to move elements following after up to prevent gaps.
list.pop() with no arguments removes the last element. Accessing that element can be done in constant time. There are no elements following so nothing needs to be shifted.
list.pop(0) removes the first element. All remaining elements have to be shifted up one step, so that takes O(n) linear time.
To add to Martijn's answer, if you want a datastructure that has constant time pops at both ends, look at collections.deque.
I know there is a list.clear(), I'm just sharing that I didn't expect that using list.pop() and list.remove() specifically could slow down the program that much.
li = list(range(500000))
Creating a list is quick.
So we are going to test out pop/remove specific values. For the purpose of this "benchmark", we are going to remove all elements from the list:
while (li):
li.pop(0)
It took 74.735 seconds to pop all the elements! It's ridiculously long.
I KNOW it would have been much faster if I even had used li.pop() without the index or maybe used filter function, list comprehension with conditional or whatever
But that's what I'm trying to show, how slow it is to remove certain list items specifically using pop and remove methods.
And li.remove(), which always requires a specified value to remove, is even worse than pop!
for num in li:
li.remove(num)This one took me 303.268 seconds to complete. How crazy it is.
I've been having fun with abstract data structures. Implemented linked lists and a queues running on linked lists.
And for the sake of interest, I decided to compare the performance of the queue based on the linked list and the usual python list. And I was surprised. When my linked list Queue dequeued 500.000 elements in 0.5 seconds, while python list Queue was doing it in 75 seconds.
Hi, I'm a beginner who has just started an introductory algorithm course. I've just finished the part on list operations and was playing around measuring runtime of each operation. I've written a function that adds consecutive numbers to the end of a list (from 1, 2, 3... to n), and other functions that remove the first or last number in that list.
Appending and popping numbers at the end of the list runs in O(1) time so it's blazing fast.
Popping the first number runs in O(n) time, so it's a bit slower.
To my surprise slicing from [1:] was extremely slow, but I thought slicing runs in O(k) time (in this case k is just n-1 so they should be similar)?
Is it the way that I've coded the function that made it slow? Is it the repeated variable assignment that slowed it down this much? Or is my time complexity analysis wrong? Thanks!
(I do realize that I'm running each list operation n times, so the time complexities of the functions are n times the time complexity of the operation, but my question remains)
import time
def add_last_num(num_list, times):
for i in range (1, times+1):
num_list.append(i)
def pop_last_num(num_list, times):
for i in range (times):
num_list.pop()
def pop_first_num(num_list, times):
for i in range(times):
num_list.pop(0)
def slice_first_num(num_list, times):
for i in range(times):
num_list = num_list[1:]
return num_list
nums = []
n = 10**5
start = time.time()
add_last_num(nums, n)
end1 = time.time()
pop_last_num(nums, n)
end2 = time.time()
add_last_num(nums, n)
end3 = time.time()
pop_first_num(nums, n)
end4 = time.time()
add_last_num(nums, n)
end5 = time.time()
nums = slice_first_num(nums, n)
end6 = time.time()
print(f"add_last_num took {end1 - start} seconds") # runtime = 0.0015 seconds
print(f"pop_last_num took {end2 - end1} seconds") # runtime = 0.0019 seconds
print(f"pop_first_num took {end4 - end3} seconds") # runtime = 0.6272 seconds
print(f"slice_first_num took {end6 - end5} seconds") # runtime = 9.6040 seconds!!