Python中的数据结构

16 投票
6 回答
23345 浏览
提问于 2025-04-15 17:31

到目前为止,我读过的所有关于数据结构的书籍似乎都使用C/C++,而且它们很依赖于手动控制指针的功能。因为Python把这种内存管理和垃圾回收的工作都隐藏起来了,难道在这个语言中实现高效的数据结构还有可能吗?而且,除了使用内置的功能,还有必要这样做吗?

6 个回答

10

C/C++的数据结构书籍主要是想教你各种结构背后的基本原理,并不是让你去自己重新发明轮子,去建立自己的栈和列表库。

无论你使用的是Python、C++、C#、Java还是其他语言,首先应该看看内置的数据结构。它们通常是用你自己实现时需要用到的基本系统功能来做的,而且经过了很多测试,比较可靠。

只有在内置的数据结构无法满足你的需求,且没有其他可靠的库可以使用时,才应该考虑从头开始自己构建东西(或者在现有的基础上进行扩展)。

14

对于一些简单的数据结构(比如栈),你可以直接用内置的列表来完成你的任务。对于更复杂的结构(比如布隆过滤器),你就需要自己动手实现了,利用语言提供的基本功能。

如果内置的功能能满足你的需求,那就尽量使用它们,因为这些功能经过很多人长时间的调试和优化,效果会更好。自己从头做可能会导致你做出的数据结构不够好。

不过,如果你需要的功能在内置的选项中没有,或者内置的功能表现得不够好,那你就得自己实现一个新的类型。

像指针管理这些细节只是实现过程中的技术讨论,并不会限制语言本身的能力。

25

Python 提供了一些强大且经过优化的数据结构,这些数据结构既有内置的,也有一些模块中的标准库(比如 listdict,当然还有 tupleset、在 array 模块中的 array,以及在 collections 模块中的其他容器)。

这些数据结构的组合(也许还包括一些辅助模块中的函数,比如 heapqbisect)通常足以实现大多数在实际编程中需要的复杂结构;不过,这并不总是适用。

当你需要的东西超出了丰富的库所提供的范围时,可以考虑一个对象的属性(以及集合中的项)本质上是指向其他对象的“指针”(没有指针运算),也就是说,在 Python 中就像在 Java 中一样,它们是“可重置的引用”。在 Python 中,通常使用 None 值来表示属性或项中的空值,这就像在 C++ 中的 NULL 或在 Java 中的 null

所以,例如,你可以通过以下方式实现二叉树:

class Node(object):

  __slots__ = 'payload', 'left', 'right'

  def __init__(self, payload=None, left=None, right=None):
    self.payload = payload
    self.left = left
    self.right = right

再加上用于遍历和类似操作的方法或函数(__slots__ 类属性是可选的——主要是为了优化内存,避免每个 Node 实例都携带自己的 __dict__,这会比需要的三个属性/引用大得多)。

其他可能更适合用专门的 Python 类来表示的数据结构,而不是直接组合其他现有的 Python 结构,包括 tries(例如可以参考 这里)和 graphs(例如可以参考 这里)。

撰写回答