It's amortized O(1), not O(1).

Let's say the list reserved size is 8 elements and it doubles in size when space runs out. You want to push 50 elements.

The first 8 elements push in O(1). The nineth triggers reallocation and 8 copies, followed by an O(1) push. The next 7 push in O(1). The seventeenth triggers reallocation and 16 copies, followed by an O(1) push. The next 15 push in O(1). The thirty-third triggers reallocation and 32 copies, followed by an O(1) push. The next 31 push in O(1). This continues as the size of list is doubled again at pushing the 65th, 129th, 257th element, etc..

So all of the pushes have O(1) complexity, we had 64 copies at O(1), and 3 reallocations at O(n), with n = 8, 16, and 32. Note that this is a geometric series and asymptotically equals O(n) with n = the final size of the list. That means the whole operation of pushing n objects onto the list is O(n). If we amortize that per element, it's O(n)/n = O(1).

Answer from rlbond on Stack Overflow
Top answer
1 of 3
208

It's amortized O(1), not O(1).

Let's say the list reserved size is 8 elements and it doubles in size when space runs out. You want to push 50 elements.

The first 8 elements push in O(1). The nineth triggers reallocation and 8 copies, followed by an O(1) push. The next 7 push in O(1). The seventeenth triggers reallocation and 16 copies, followed by an O(1) push. The next 15 push in O(1). The thirty-third triggers reallocation and 32 copies, followed by an O(1) push. The next 31 push in O(1). This continues as the size of list is doubled again at pushing the 65th, 129th, 257th element, etc..

So all of the pushes have O(1) complexity, we had 64 copies at O(1), and 3 reallocations at O(n), with n = 8, 16, and 32. Note that this is a geometric series and asymptotically equals O(n) with n = the final size of the list. That means the whole operation of pushing n objects onto the list is O(n). If we amortize that per element, it's O(n)/n = O(1).

2 of 3
61

If you look at the footnote in the document you linked, you can see that they include a caveat:

These operations rely on the "Amortized" part of "Amortized Worst Case". Individual actions may take surprisingly long, depending on the history of the container.

Using amortized analysis, even if we have to occasionally perform expensive operations, we can get a lower bound on the 'average' cost of operations when you consider them as a sequence, instead of individually.

So, any individual operation could be very expensive - O(n) or O(n^2) or something even bigger - but since we know these operations are rare, we guarantee that a sequence of O(n) operations can be done in O(n) time.

🌐
Reddit
reddit.com › r/learnpython › what is python's list.append() method worst time complexity? it can't be o(1), right?
r/learnpython on Reddit: What is Python's list.append() method WORST Time Complexity? It can't be O(1), right?
October 26, 2022 -

I know that lists in Python are implemented using arrays that store addresses to the information. Therefore, after several appends, when an array is loaded, it needs to reserve a new space and copy the entire array of addresses to the new place.

I've read on Stackoverflow that in Python Array doubles in size when run of space. So basically it has to copy all addresses log(n) times.

The bigger the list, the more copying it will need to do. So how can append operation have a Constant Time Complexity O(1) if it has some dependence on the array size

I assume since it copies addresses, not information, it shouldn't take long, python takes only 8 bytes for address after all. Moreover, it does so very rarely. Does that mean that O(1) is the average time complexity? Is my assumption right?

Top answer
1 of 4
4
I've read on Stackoverflow that in Python Array doubles in size when run of space It's actually not double, but it does increase proportional to the list size (IIRC it's about 12%, though there's some variance at smaller sizes). This does result in the same asymptotics though, so I'll assume doubling in the following description for simplicity. So basically it has to copy all addresses log(n) times. Not quite. Suppose we're appending n items to an empty vector. We will indeed do log(n) resizes, so you might think "Well, resizes are O(n), so log(n) resizes is n log(n) operations, which if we amortize over the n appends we did means n log(n)/n, or log(n) per append". However, there's a flaw in this analysis: we do not copy "all addresses" each of those times. Ie. the copies are not O(n). Sure, the last copy we do will involve copying n items, but the one before it only copied n/2, and so on. So we actually do 1 + 2 + 4 + ... + n copies, which sums to 2n-1. Divide that by n and you get ~2 operations per append - a constant. I assume since it copies addresses, not information We are indeed only copying the pointer, but this doesn't really matter for the complexity analysis. Even if it was copying a large structure, that'd only increase the time by a constant factor. Does that mean that O(1) is the average time complexity? It's the amortized worst case complexity (ie. what happens over a large number of operations). While any one operation can indeed end up doing O(n) operations, there's an important distinction that over a large number of operations, you are guaranteed to only be O(1), which is a distinction just talking about average case wouldn't capture.
2 of 4
2
Personally, I thought that lists worked as double LinkedLists, so insert time was O(1) But if it works as a dynamic array, time complexity should be amortized time, ie, close to O(1) but not quite
Discussions

How is the time complexity of the prepend and append in List object constant and linear?
The time complexities be like that because Lists are "Linked Lists". Appending requires traversing the whole collection to get to the end before appending the element. More on reddit.com
🌐 r/scala
12
1
June 1, 2020
Time Complexity of Python list comprehension then list[i] = value vs. list = [] then list.append(value)
In terms of Big O the algorithms are equivalent to each other as they both have linear growth. As you say, the list comprehension in the first example is O(n) so the function is O(2n), but in algorithmic analysis that is considered equivalent to O(n). In practical terms the second approach is better as it only requires one iteration over the input array. More on reddit.com
🌐 r/learnprogramming
5
2
September 26, 2021
What is the time complexity of adding two arrays?
I would assume O(n) since it needs to get a new bit of continuous memory and copy the first then second array into it. More on reddit.com
🌐 r/ruby
13
7
December 30, 2019
What is the time complexity of using slices as stacks/queues?
Slice is just a view into underlying array. For stack single array for maximum size will be allocated. Once it is allocated, you pay only for changing size variable (field in structure), ie O(1) . For queue it is a bit more complex. Let’s assume, queue has regular length (is it doesn’t change a lot). Then every L (len(queue)) push+pop operations new array of 2L (at max) elements will be allocated. If we count cost of allocation as O(2L)=O(L), then amortized cost per operation is O(2L)/L=O(1) . Ie queue also has amortized constant cost of operation. (It could be shown this conclusion remains correct even if size of queue changes a lot) More on reddit.com
🌐 r/golang
5
7
October 4, 2019
🌐
GeeksforGeeks
geeksforgeeks.org › python › time-complexity-for-adding-element-in-python-set-vs-list
Time Complexity for Adding Element in Python Set vs List - GeeksforGeeks
July 23, 2025 - When we add an element to a list using the append() method, Python directly adds the element to the end. This operation has O(1) amortized time complexity, as no hashing or duplicate checks are needed.
🌐
Bacancy Technology
bacancytechnology.com › qanda › python › pythons-list-append-method-has-01-time-complexity
Why Python’s list.append() Method Has O(1) Time Complexity
July 14, 2025 - Appending to a list is considered amortized O(1) time complexity. Here’s why: When the array runs out of space, Python allocates a larger block of memory (usually more than double the current size) and copies all elements to the new space.
🌐
Scaler
scaler.com › home › topics › python › append in python
Python List append() Method with Examples - Scaler Topics
May 16, 2023 - Whenever the combined size of elements of that list exceeds the memory space of the original list, it acquires the contiguous memory at another location of size double its previous size. In that scenario, the previous elements are copied to this new memory space, and new elements are appended to the list. So, this is considered as the worst case for appending any element to the list and the time complexity for this worst case is O(N) where N is the size of the original list.
🌐
Python
wiki.python.org › moin › TimeComplexity
TimeComplexity
(Well, a list of arrays rather than objects, for greater efficiency.) Both ends are accessible, but even looking at the middle is slow, and adding to or removing from the middle is slower still. See dict -- the implementation is intentionally very similar. As seen in the source code the complexities for set difference s-t or s.difference(t) (set_difference()) and in-place set difference s.difference_update(t) (set_difference_update_internal()) are different!
🌐
LabEx
labex.io › tutorials › python-what-is-the-time-complexity-of-list-append-and-remove-operations-in-python-397728
What is the time complexity of list append and remove operations in Python | LabEx
The time complexity of an algorithm is typically expressed using Big O notation, which provides an upper bound on the growth rate of the algorithm's running time as the input size increases.
Find elsewhere
🌐
Medium
medium.com › @ivanmarkeyev › understanding-python-list-operations-a-big-o-complexity-guide-49be9c00afb4
Understanding Python List Operations: A Big O Complexity Guide | by Ivan Markeev | Medium
June 4, 2023 - In the worst case, where the element ... or removing an element at the end of a Python list is an efficient operation with constant time complexity....
🌐
PREP INSTA
prepinsta.com › home › data structures and algorithms in python › introduction to stack in python
Introduction to Stack in Python | PrepInsta
June 27, 2025 - stack.append(x) adds x to the top of the stack (end of the list). stack.pop() removes the last item (LIFO behavior). stack[-1] accesses the current top without removing it. Complexity: Time Complexity: O(1) for push/pop/peek · Space Complexity: ...
🌐
Hero Vired
herovired.com › learning-hub › topics › append-function-in-python
Understanding Append Function in Python with Examples
When you use the ‘append()’ method, Python typically adds the new element without needing to reallocate or move the existing elements, resulting in an average-case time complexity of O(1).
🌐
FITA Academy
fita.in › length-of-list-in-python
Length of List in Python | Python List Size | Python Array Length
Prashanth
In this blog, Get to know about the Lenght of Lists in Python and its attributes in the different methods. I joined in FITA to pursue Expertise in Digital Marketing. The training they had given to me is wonderful and they taught more tools and working knowledge in digital marketing. Efficient trainer. He gave me many tips and tricks on how to handle and survive in the field of digital marketing. Overall its a best place to learn Digital marketing course. FITA is a leading Training and Placement company managed by IT veterans with more than a decade of experience in leading MNC companies. We ar
Rating: 5 ​
Call   9345045466
Address   Plot No 7, 2nd floor, Vadivelan Nagar, Velachery Main Road, Velachery, 600042, Chennai
🌐
Cybrosys Technologies
cybrosys.com › odoo blogs
What Are the Best Practices in Python Coding for Odoo 16 Development
In this blog, we delve into the core principles of coding excellence in Odoo 16 using Python.
🌐
Essinstitute
onlinecourse.essinstitute.in › home › resources › basics of stack and its operations in python | python course in delhi
Basics of Stack and its operations in Python | Python course in Delhi
July 4, 2024 - Thus, if you are looking for a stack in the Python standard library, but want to have it with the runtime complexity of a linked list implementation, collections.deque would be the best option. ... stack = deque() # Push elements onto the stack stack.append('apple') stack.append('banana') stack.append('cherry') print(stack) # Output: deque(['apple', 'banana', 'cherry']) print(stack.pop()) # Output: 'cherry' print(stack.pop()) # Output: 'banana' print(stack.pop()) # Output: 'apple' try: print(stack.pop()) except IndexError as e: print("Error:", e) # Output: Error: pop from an empty deque
🌐
Board Infinity
boardinfinity.com › blog › stack-in-python
Stack in Python | Board infinity
August 9, 2025 - To add an item to the top of the stack, we use the append() method. To remove an item from the top of the stack, we use the pop() method. ... Below is the syntax used for defining the Stack in python, we can initialize a stack just like a list: ... top() / peek() – This method returns a reference to the topmost element of the stack in Time Complexity: O(1)
🌐
Shiksha
shiksha.com › home › it & software › it & software articles › programming articles › how to use append python function
How to use Append Python Function - Shiksha Online
August 27, 2024 - In simple terms, a Python dictionary is a flexible sized arbitrary collection of key-value pairs, where key and value both are Python objects. ... Element in append () function passed as an argument will be added at the end of the list. ... Each element of the iterable passed as an argument gets added at the end of the list. The list length is increased by the number of elements in the iterable. Time Complexity: O(n), where n is the length of the iterable
🌐
Parseltongue
parseltongue.co.in › how-python-lists-work-internally
ParselTongue - How Python Lists Work Internally
To minimize frequent resizing, Python uses a growth factor:The size of the new array is roughly 1.125x the current size (implementation-specific). This ensures that resizing happens less frequently as the list grows. Time Complexity of List Operations · Access (list[i]) O(1) Direct access to elements using an index. Append (list.append) Amortized O(1) Resizing may occasionally make this O(n).
🌐
Vista Academy
thevistaacademy.com › home › blog › python array vs list: key differences and when to use each [2025 updated]
Python Array vs List: Key Differences and When to Use Each [2025 Updated]
August 21, 2025 - Confused between array and list in Python? Learn the key differences, performance comparison, memory usage, and when to use each. Includes code examples and best practices for Python beginners and data analysts.
🌐
DigitalBitHub
digitalbithub.com › home › python › deque - python collection module
Deque - Python Collection Module | DigitalBitHub
A deque, short for double-ended queue, is a dynamic array that allows for quick and efficient append and pop operations on both ends. It provides O(1) time complexity for these operations, making it a valuable tool in scenarios where performance ...
🌐
Geek Python
geekpython.in › insert-vs-append-vs-extend
Difference Between insert(), append() And extend() In Python With Examples
August 15, 2023 - append() – This method is used to add the element to the end of the list. extend() – This method is used to add each item from the iterable to the end of the list. 🏆Other articles you might be interested in if you liked this one ... First and foremost, thank you for taking the time to read my articles. I'm Sachin Pal, a Python enthusiast who enjoys sharing my projects and writings on this tech blog.