Python中从列表中弹出元素的时间复杂度是多少?

Hal*_*dun 43 python

我想知道Python中列表对象的pop方法的时间复杂度是什么(特别是在CPython中).list.pop(N)的N值也会影响复杂性吗?

Dan*_*ski 37

是的,弹出Python列表的最后一个元素是O(1),弹出任意元素是O(N)(因为必须移动列表的其余部分).

这是一篇关于如何存储和操作Python列表的精彩文章:http://effbot.org/zone/python-list.htm

  • 所以为了说清楚,list.pop(0)是O(n)而list.pop()是O(1). (17认同)
  • @galath:需要明确的是,`deque` 不是用于删除任意项的 O(1) (你没有明确指出,*我只是想确保没有误解),因为它是一个双向链表块(即*数组*),而不是单个元素。因此它通常仍然是 O(n)。删除双端队列中的第一项的时间复杂度为 O(1),因为该块具有开始索引和结束索引,可以在不移动元素的情况下对其进行操作。 (3认同)
  • 要同时在O(1)中进行这两种操作,请使用collections.deque参见[here](https://wiki.python.org/moin/TimeComplexity) (2认同)

tva*_*son 30

Pop()因为你只需要返回数组中最后一个元素引用的元素并更新最后一个元素的索引,因此最后一个元素应该是O(1).我希望pop()任意元素为O(N)并且需要平均N/2次操作,因为你需要移动任何元素超出你在指针数组中移除一个位置的元素.

  • 我同意给出的答案,但解释是错误的。您可以在 O(1) 时间从列表中删除任何对象(本质上是使 prev 指针指向下一个,然后删除它)问题是为了找到该位置的对象,您需要遍历列表直到点(花费 O(N) 时间,不需要平均。)最后一个特殊情况注意:pop(0) 将花费 O(1),而不是 O(0)。 (4认同)
  • @ntg 列表是一个指针数组。要从中间的数组中删除一个指针,它后面的所有指针都必须在数组中向上移动,所花费的时间与列表的大小(我们表示为 N)成正比,因此是 O(N) . 澄清 Big-O 符号中的 N 不是返回元素的索引,而是一个用 O(1) 为常数时间来限制算法运行时间的函数——即,它不依赖于列表。O(N) 意味着边界函数是列表大小的常数倍,f(n) = c*n + b。 (4认同)

Pyt*_*ner 7

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
Run Code Online (Sandbox Code Playgroud)


Gwa*_*r17 6

简短的答案是在这里:https : //wiki.python.org/moin/TimeComplexity

没有参数弹出其O(1)

弹出一个参数:

  • 平均时间复杂度O(k)(k表示作为pop参数传入的数字
  • 摊销最坏情况时间复杂度O(k)
  • 最坏情况下的时间复杂度O(n)

平均时间复杂度:

  • 每当您输入一个值时,该操作的时间复杂度为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)

最坏情况下的时间复杂度

  • 与摊销最坏情况下的时间复杂度不同,您不必考虑数据结构的状态,而只考虑任何单个操作的最坏情况。
  • 在这种情况下,最坏的情况是您必须从列表中删除时间为O(n)的第一项。

如果有帮助,请考虑以下几点: