【发布时间】:2008-10-12 15:58:59
【问题描述】:
我想知道 Python 中列表对象的 pop 方法的时间复杂度是多少(特别是在 CPython 中)。 list.pop(N) 的 N 值也会影响复杂性吗?
【问题讨论】:
标签: python
我想知道 Python 中列表对象的 pop 方法的时间复杂度是多少(特别是在 CPython 中)。 list.pop(N) 的 N 值也会影响复杂性吗?
【问题讨论】:
标签: python
是的,弹出 Python 列表的 last 元素是 O(1),弹出一个 任意 元素是 O(N)(因为剩下的全部列表的一部分必须移动)。
这是一篇关于如何存储和操作 Python 列表的精彩文章:http://effbot.org/zone/python-list.htm
【讨论】:
deque 不是 O(1) 用于删除任意项目(您没有明确说明, 我只是想要以确保没有误解),因为它是块的双向链表(即数组),而不是单个元素。因此它通常仍然是 O(n)。删除双端队列中的第一项是 O(1),因为该块具有开始和结束索引,可以在不移动元素 s 的情况下对其进行操作。
deque.pop 不接受参数 docs on deque,就像列表中的 pop 方法一样。它删除了最右边的元素。
Pop() 最后一个元素应该是 O(1) 因为你只需要返回数组中最后一个元素引用的元素并更新最后一个元素的索引。我希望pop() 的任意元素为 O(N) 并且平均需要 N/2 次操作,因为您需要将任何元素移动到要在指针数组中向上删除一个位置的元素之外。
【讨论】:
L.pop(-1) 应该是 O(1),L.pop(0) 应该是 O(n)
参见以下示例:
from timeit import timeit
if __name__ == "__main__":
L = range(100000)
print timeit("L.pop(0)", setup="from __main__ import L", number=10000)
L = range(100000)
print timeit("L.pop(-1)", setup="from __main__ import L", number=10000)
>>> 0.291752411828
>>> 0.00161794329896
【讨论】:
L.pop(-1) 有什么区别
简短的答案请看这里:https://wiki.python.org/moin/TimeComplexity
没有参数来弹出它的 O(1)
带参数pop:
平均时间复杂度:
任何时候输入一个值,该操作的时间复杂度都是 O(n - k)。
例如,如果您有一个包含 9 个项目的列表,则从列表末尾删除是 9 个操作并从开头删除 该列表是 1 个操作(删除第 0 个索引并移动所有 其他元素的当前索引 - 1)
由于列表中间元素的 n - k 是 k 次操作,因此平均值可以缩短到 O(k)。
另一种思考方式是假设每个索引都从您的 9 项列表中删除了一次。那将是总共 45 次操作。 (9+8+7+6+5+4+3+2+1 = 45)
45 等于 O(nk) 并且由于弹出操作发生了 O(n) 次,因此您将 nk 除以 n 得到 O(k)
摊销的最坏情况时间复杂度
假设您又有一个包含 9 个项目的列表。想象一下,您正在删除列表中的每一项,而最坏的情况发生了,您每次都删除了列表中的第一项。
由于列表每次缩小 1,因此总操作数每次从 9 减少到 1。
9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 = 45。45 等于 O(nk)。由于您进行了 9 次操作,并且 9 是 O(n) 来计算摊销的最坏情况,因此您执行 O(nk) / O(n) 等于 O(k)
说明平均和摊销的最坏情况时间复杂度为 O(n) 也是正确的。请注意,O(k) 大约为 O(1/2n),删除常数等于 O(n)
最坏情况时间复杂度
【讨论】: