15

Just learning Python. Reading through the official tutorials. I ran across this:

While appends and pops from the end of list are fast, doing inserts or pops from the beginning of a list is slow (because all of the other elements have to be shifted by one).

I would have guessed that a mature language like Python would have all sorts of optimizations, so why doesn't Python [seem to] use linked lists so that inserts can be fast?

loneboat
  • 2,845
  • 5
  • 28
  • 40

5 Answers5

26

Python uses a linear list layout in memory so that indexing is fast (O(1)).

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
10

As Greg Hewgill has already pointed out, python lists use contiguous blocks of memory to make indexing fast. You can use a deque if you want the performance characteristics of a linked list. But your initial premise seems flawed to me. Indexed insertion into the middle of a (standard) linked list is also slow.

senderle
  • 145,869
  • 36
  • 209
  • 233
  • I should have clarified my premise. Meant to say, "... so that inserts towards the beginning are fast." – loneboat Sep 05 '12 at 13:28
6

What Python calls "lists" aren't actually linked lists; they're more like arrays. See the list entry from the Python glossary and also How do you make an array in Python? from the Python FAQ.

jamesdlin
  • 81,374
  • 13
  • 159
  • 204
5

list is implemented as an arraylist. If you want to insert frequently, you can use a deque (but note that traversal to the middle is expensive).

Alternatively, you can use a heap. It's all there if you take the time to look at the docs.

Marcin
  • 48,559
  • 18
  • 128
  • 201
5

Python lists are implemented using a resizeable array of references to other objects. This provides O(1) lookup compared to O(n) lookup for a linked list implementation.

See How are lists implemented?

As you mentioned, this implementation makes insertions into the beginning or middle of a Python list slow because every element in the array to the right of the insertion point has to be shifted over one element. Also, sometimes the array will have to be resized to accommodate more elements. For inserting into a linked list, you'll still need O(n) time to find the location where you will insert, but the actual insertion itself will be O(1), since you only need to change the references in the nodes immediately before and after your insertion point (assuming a doubly-linked list).

So the decision to make Python lists use dynamic arrays rather than linked lists has nothing to do with the "maturity" of the language implementation. There are simply trade-offs between different data structures and the designers of Python decided that dynamic arrays were the best option overall. They may have assumed indexing a list is more common than inserting data into it, thus making dynamic arrays a better choice in this case.

See the following table in the Dynamic Array wikipedia article for a comparison of various data structure performance characteristics:

https://en.wikipedia.org/wiki/Dynamic_array#Performance

ben_frankly
  • 9,270
  • 3
  • 18
  • 22