python是否有内置的链接List数据结构?

时间:2013-02-03 02:04:18

标签: python-2.7

有人知道Python(可能是2.7)是否有内置的linkedList数据结构?我知道队列是使用list实现的,并且没有堆栈(有LIFO队列)。

5 个答案:

答案 0 :(得分:9)

是的,Python的collections module提供了C实现的deque对象,它在内部使用了BLOCK的链接列表。

typedef struct BLOCK {
    struct BLOCK *leftlink;
    PyObject *data[BLOCKLEN];
    struct BLOCK *rightlink;
} block;

typedef struct {
    PyObject_VAR_HEAD
    block *leftblock;
    block *rightblock;
    Py_ssize_t leftindex;       /* 0 <= leftindex < BLOCKLEN */
    Py_ssize_t rightindex;      /* 0 <= rightindex < BLOCKLEN */
    size_t state;               /* incremented whenever the indices move */
    Py_ssize_t maxlen;          /* maxlen is -1 for unbounded deques */
    PyObject *weakreflist;
} dequeobject;

static PyTypeObject deque_type;

答案 1 :(得分:3)

除非您确实需要针对特定​​内容的显式链接列表结构,否则Python的内置列表具有您从链接列表中获得的所有功能。例如,您可以将其用作堆栈,如下所示:

>>> x = []
>>> x.append(1)
>>> x.append(2)
>>> x
[1, 2]
>>> x.pop()
2
>>> x
[1]
>>>

或者,在给定元素之后插入元素:

>>> x = [1,2,3,4,5,6,7]
>>> x.insert(3,"a")
>>> x
[1, 2, 3, 'a', 4, 5, 6, 7]
>>> 

例如,请参阅data structures上的Python文档。

但是,这是使用“list”抽象数据类型(ADT)。相反,“链表”不是ADT,而是实现该ADT的许多可能方式之一。

如果前置效率是一个问题,ŁukaszRogalski的答案指出collections.deque是使用链表实现的。正如Using Lists as Queues所述:

  

也可以使用列表作为队列,其中添加的第一个元素是检索到的第一个元素(“先进先出”);但是,列表不能用于此目的。虽然列表末尾的追加和弹出快速,但从列表的开头进行插入或弹出是很慢的(因为所有其他元素都必须移动一个)。

     

要实现队列,请使用collections.deque,它设计为具有快速追加和两端弹出。

为了测试使用listdeque的效率影响,我使用了以下程序:

import timeit, sys

print ("append to list: %f" % (timeit.timeit ('x.append("x")', 'x = ["y"]')))
print ("insert to list element 0: %f" % (timeit.timeit ('x.insert(0,"x")', 'x = ["y"]')))
print ("append to deque: %f" % (timeit.timeit ('x.append("x")', 'import collections; x = collections.deque(["a","b","c"])')))
print ("append left to deque: %f" % (timeit.timeit ('x.appendleft("x")', 'import collections; x = collections.deque(["a","b","c"])')))

if (sys.version_info[0]+sys.version_info[1]/10) > 3.4999:
    print ("insert in deque: %f" % (timeit.timeit ('x.insert(2,"x")', 'import collections; x = collections.deque(["a","b","c"])')))

...并获得了Python 3.6和Python 2.7的以下结果:

$ python3 testList.py
append to list: 0.113031
insert to list element 0: 191.147079
append to deque: 0.058606
append left to deque: 0.064640
insert in deque: 0.160418

$ python testList.py
append to list: 0.102542
insert to list element 0: 191.128508
append to deque: 0.083397
append left to deque: 0.064534

因此,list大约需要两倍的时间来追加元素dequedeque花费更少的时间来预先添加(即附加到左侧)而不是追加。

答案 2 :(得分:2)

python中没有内置的链表,但是你可以使用dequeue,它既可以访问头部也可以是尾部,但如果你想实现你自己的链表可能是你可以使用

Python Linked List

答案 3 :(得分:1)

我相信集合包中的deque类是作为双向链表实现的,具有头部和尾部保护。它支持默认列表的所有常用API。要附加到头部,请使用leftappend功能。

from collections import deque

答案 4 :(得分:0)

Python有collections.deque,它是小list()的双向链接列表。

尽管使用Python list()而不是链接列表,几乎总是更好。即使链表在某些操作上具有出色的big-O,但由于引用的位置更好,所以list()常常会更快。

我实际上在Python中玩了链表: http://stromberg.dnsalias.org/~strombrg/linked-list/ ...在进行性能比较之前。

我使用“计数”程序作为测试平台;与链表相比,它比使用list()的版本更慢并且使用了更多的RSS(RAM)。计数为http://stromberg.dnsalias.org/~strombrg/count.html 我扔掉了它的链表版本。它并不是非常有用。

某种意义上说list()有时会更快。考虑在list()和链表中从第一个元素到最后一个元素进行遍历。 list()倾向于对n个元素引用执行单个RAM缓存命中,而链接列表倾向于对每个元素进行单个RAM缓存命中。这是因为list()引用在RAM中彼此相邻,但是链接的列表引用对于每个值都在不同的类实例中。缓存要比常规RAM快得多,这可能会很重要。

collections.deque并不会因此而牺牲太多,因为组成链表中每个节点的数组很小。

另一方面,如果要避免人们使用随机访问值的集合,则链表可能是一个好主意。也就是说,有时为了抽象起见,您可能更喜欢链表而不是list()。但是Python开发人员倾向于假设“我们都是成年人”。

此外,如果您已经知道将新值放在哪里(即,不需要O(n)搜索来确定将其放在哪里),则插入列表的中间,这是一个链表更快一点。