它是链表还是数组?我四处搜寻,只发现人们在猜测。我的C语言知识还不够好,不能看源代码。
当前回答
这取决于实现,但IIRC:
CPython使用指针数组 Jython使用数组列表 IronPython显然也使用数组。您可以浏览源代码来找到答案。
因此它们都有O(1)个随机访问。
其他回答
正如上面其他人所述,列表(当相当大时)是通过分配固定数量的空间来实现的,如果该空间应该被填满,则分配更大数量的空间并复制元素。
To understand why the method is O(1) amortized, without loss of generality, assume we have inserted a = 2^n elements, and we now have to double our table to 2^(n+1) size. That means we're currently doing 2^(n+1) operations. Last copy, we did 2^n operations. Before that we did 2^(n-1)... all the way down to 8,4,2,1. Now, if we add these up, we get 1 + 2 + 4 + 8 + ... + 2^(n+1) = 2^(n+2) - 1 < 4*2^n = O(2^n) = O(a) total insertions (i.e. O(1) amortized time). Also, it should be noted that if the table allows deletions the table shrinking has to be done at a different factor (e.g 3x)
它是一个动态数组。实践证明:无论索引如何,索引都需要相同的时间(当然差异非常小(0.0013µs !)):
...>python -m timeit --setup="x = [None]*1000" "x[500]"
10000000 loops, best of 3: 0.0579 usec per loop
...>python -m timeit --setup="x = [None]*1000" "x[0]"
10000000 loops, best of 3: 0.0566 usec per loop
如果IronPython或Jython使用链表,我会感到震惊——它们会破坏许多广泛使用的库的性能,这些库建立在链表是动态数组的假设之上。
这取决于实现,但IIRC:
CPython使用指针数组 Jython使用数组列表 IronPython显然也使用数组。您可以浏览源代码来找到答案。
因此它们都有O(1)个随机访问。
根据文档,
Python的列表实际上是变长数组,而不是lisp风格的链表。
在CPython中,列表是指针的数组。Python的其他实现可以选择以不同的方式存储它们。