【发布时间】:2020-11-19 03:52:58
【问题描述】:
我从this answer 了解到,在索引处插入项目的最快方法是这样的:
a = [1, 2, 3, 4, 5]
a[2:2] = ["12345"]
但我不知道为什么。我从this answer 了解到,复杂度永远不会是 O(1)。
我尝试了以下并验证了它应该大于O(1)的说法。
python3 -m timeit --setup="a = list(range(1000))" "a[500:500] = [3]"
50000 loops, best of 5: 3.89 usec per loop
python3 -m timeit --setup="a = list(range(100000))" "a[500:500] = [3]"
10000 loops, best of 5: 20.1 usec per loop
python3 -m timeit --setup="a = list(range(1000000))" "a[500:500] = [3]"
1000 loops, best of 5: 340 usec per loop
我认为我们可以在 O(1) 中 pinpoint the address/pointer 然后我们只需将该地址指向新项目,它会是 O(1)。我认为我应该是错的,因为这会跳过右侧项目的地址。
我试图查看a[2:2] 是什么,但结果只是一个空列表。我认为可以将索引和分配分开。我的意思是如果我们可以先获取特定索引的指针,然后让它指向一个新项目?
In [14]: a = [1, 2, 3, 4, 5]
In [15]: b = a[2:2]
In [16]: b = ["12345"]
In [17]: b
Out[17]: ['12345']
In [18]: a
Out[18]: [1, 2, 3, 4, 5]
In [19]: a[2:2] = ["12345"]
In [20]: a
Out[20]: [1, 2, '12345', 3, 4, 5]
在上面的代码中,我想通过b=a[2:2] 获取指针,然后通过b = ["12345"] 将其重定向到新项目"12345"。
引擎盖下发生了什么?任何建议将不胜感激。提前致谢。
【问题讨论】:
-
当您尝试测量不同大小列表的插入操作时间时,您发现了什么?
-
这个答案提供了解释和链接,以进一步阅读有关幕后情况的材料:How is Python's List Implemented?
-
您链接的第一个问题,我无法重现不同的时间。它报告
list.insert与切片分配相比要慢 8 倍(!)。这似乎不切实际(即使对于旧版本的 Python),我在 Python 3.8 上也获得了相同的性能。此操作是否为 O(1) 取决于列表类型的实现。但对于大多数实现来说,它不会是 O(1)。 -
平均而言,在
list中插入的时间复杂度为O(1),但在最坏的情况中可能是O(n)的复杂度。 -
@FishingCode 请注意,它表示 在结尾。
标签: python python-3.x list time-complexity