我找到了这个问题并想提供一个带有一些背景的例子。
使用Deque的经典用例可能是在集合中旋转/移动元素,因为(正如其他人提到的那样),对于两端的push/pop操作,您可以获得非常好的(O(1))复杂度,因为这些操作只是在移动引用,而不是像列表一样必须在内存中物理移动对象。
所以这里有两个非常相似的左旋实现:(rotate-left function)
def rotate_with_list(items, n):
l = list(items)
for _ in range(n):
l.append(l.pop(0))
return l
from collections import deque
def rotate_with_deque(items, n):
d = deque(items)
for _ in range(n):
d.append(d.popleft())
return d
注意:这是deque的一个常见用法,deque有内置的rotate
方法,但为了视觉比较而在这里手动执行。
现在让我们使用%timeit
。
In [1]: def rotate_with_list(items, n):
...: l = list(items)
...: for _ in range(n):
...: l.append(l.pop(0))
...: return l
...:
...: from collections import deque
...: def rotate_with_deque(items, n):
...: d = deque(items)
...: for _ in range(n):
...: d.append(d.popleft())
...: return d
...:
In [2]: items = range(100000)
In [3]: %timeit rotate_with_list(items, 800)
100 loops, best of 3: 17.8 ms per loop
In [4]: %timeit rotate_with_deque(items, 800)
The slowest run took 5.89 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 527 µs per loop
In [5]: %timeit rotate_with_list(items, 8000)
10 loops, best of 3: 174 ms per loop
In [6]: %timeit rotate_with_deque(items, 8000)
The slowest run took 8.99 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 1.1 ms per loop
In [7]: more_items = range(10000000)
In [8]: %timeit rotate_with_list(more_items, 800)
1 loop, best of 3: 4.59 s per loop
In [9]: %timeit rotate_with_deque(more_items, 800)
10 loops, best of 3: 109 ms per loop
很有趣的是,这两种数据结构展示了一个惊人地相似的界面,但却有着截然不同的性能表现 :)
range
或xrange
)创建一个deque
对象需要O(n)的时间。 - Jayanth Koushik.pop
。 - vaultah