As per mentioned in the Python wiki. Time complexities are as follows:
- Pop last
O(1) - Delete Item
O(n) - Set Slice
O(k+n)
Experimental Study
import time
all_t = 0.
for i in range(1000):
list_ = [i for i in range(100000)]
start_ = time.time()
list_.pop()
all_t += time.time() - start_
print("Average Time for POP is {}".format(all_t/1000.))
all_t = 0.
for i in range(1000):
list_ = [i for i in range(100000)]
start_ = time.time()
del list_[-1]
all_t += time.time() - start_
print("Average Time for DEL is {}".format(all_t/1000.))
all_t = 0.
for i in range(1000):
list_ = [i for i in range(100000)]
start_ = time.time()
list_ = list_[:-1]
all_t += time.time() - start_
print("Average Time for SLICE is {}".format(all_t/1000.))
Results
Average Time for POP is 7.793903350830078e-07
Average Time for DEL is 9.80854034423828e-07
Average Time for SLICE is 0.0006206443309783935
Summary
pop() is the fastest when you do not specify an index.
So I was performing an experiment on the execution speed of the remove function on different list lengths and on three different positions of the list.
plot of running times
Green, blue and red plots denote the running times of the operation for the last element, middle element and the first element respectively.
Since remove works by shifting the subsequent elements to the left, I'd assume it'd take more time for remove to execute on the first element, k = 0, as the element shifting would be expensive. Then why is removing the last element more time consuming, by a large margin?
I was trying to write a simple application, which is ao supposed to filter a list of words down to a list of words of a certain length. For that I could either remove the words of the wrong length, or create a new list of words with the correct length.
I had a list of around 58000 words, and wanted to filter out all the 6 letter words, which are around 6900.
with open('words.txt') as f:
words = f.readlines()
for i in range(len(words)):
words[i] = words[i].strip()
length = int(input("Desired word length "))
for i in reversed(words):
if len(i) != length:
words.remove(i)This took 22 seconds.
Another way is to just create a new list with words of the correct length. I did this as follows:
with open('words.txt') as f:
words = f.readlines()
for i in range(len(words)):
words[i] = words[i].strip()
length = int(input("Desired word length "))
clw = []
for i in words:
if len(i) == length:
clw.append(i)This only took 0.03 seconds. How can it be that creating a list of 6900 words takes 0.03 seconds, but removing 51100 words takes 22? It's only 7 times as many words, but takes 700 times as long. And is there a better and faster way to quickly remove list elements?
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.
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.
From my understanding the reason why removing the last element is O(1) is because you don't need to shift the array in memory. You simply remove the last element and leave the old space empty. So why is it that if you remove the first element that the Array HAS to to shift in memory (making it O(n))?
I don't understand the reasoning, if we are okay with leaving empty space in memory at the end of an array and not shifting all the other things surrounding the array in memory. Then why do we have to shift the array in memory if there is space that the start?
I am not understanding, if it's because the memory is trying to stay compact and no empty spaces are allowed. Then why don't all the other stuff in memory be shifted to the left after new space was cleared once we removed the last element from the array?