为啥 Python 列表在实现为动态数组时称为“列表”

Posted

技术标签:

【中文标题】为啥 Python 列表在实现为动态数组时称为“列表”【英文标题】:Why are Python Lists called 'lists' when they are implemented as dynamic arrays为什么 Python 列表在实现为动态数组时称为“列表” 【发布时间】:2018-08-04 14:21:22 【问题描述】:

我不是如何实现 Python 列表的专家,但据我了解,它们是作为动态数组而不是链表实现的。因此,我的问题是,如果 python 列表被实现为数组,为什么它们被称为“列表”而不是“数组”。

这只是一个语义问题还是背后有一些更深层次的技术原因。 Python 中的动态数组实现是否接近于列表实现?还是因为动态数组实现使其行为比数组更接近列表的行为?还是其他我不明白的原因?

需要明确的是,我并没有具体询问 Python 列表如何或为什么实现为动态数组,尽管这可能与答案相关。

【问题讨论】:

确实是一个数组。但我对命名的有根据的猜测是,array 通常在许多语言中都暗示 all of the same type。在 Python 中并非如此。 arrays 在 Python 中(例如在 array.array 中)是某种类型的同构容器。 lists 包含 any 对象。此外 - 数组因为它们通常用于不可变类型,所以可以共享切片范围的“视图”,这样就不会进行复制。请参阅:例如docs.python.org/3/library/stdtypes.html#memoryview 甚至numpy.arrays 数组通常包含相同数据类型的元素。但是,另一方面,列表可以包含所有数据类型的元素。 它们以list abstract data type 命名,而不是链表。 【参考方案1】:

它们以list abstract data type 命名,而不是链表。这类似于Java的List接口和C#的List<T>的命名。

【讨论】:

【参考方案2】:

如***文章中所指出的,进一步详细说明user2357112's answer:

在计算机科学中,列表或序列是一种抽象数据类型, 表示可数个有序值,其中相同的值 可能不止一次。

进一步,

列表数据类型通常使用数组数据结构或某种链表来实现,但其他数据结构可能更适合某些应用程序。

在 CPython 中,列表被实现为指针的动态数组,它们的行为比Array abstract data type 更接近于 List 抽象数据类型。从这个角度来看,“List”的命名是准确的。

【讨论】:

【参考方案3】:

在实现列表的一天结束时,您想要的是常量(O(1))访问(a [i]),插入(a.append(i))和删除(a.remove(i) ) 次。对于链表,其中一些操作可能会像 O(n) 一样慢,即如果您没有指向尾部的指针,则删除链表的最后一个元素。

使用动态数组,您可以获得恒定的删除和访问时间,但是删除呢?在这里,我们得到摊销的常数时间。那是什么?如果数组中充满了 N 个元素,则插入将花费 O(N) 并且您最终会得到一个大小为 2N 的数组。这是一个罕见的事件,因此我们说我们已经摊销了 O(1)。

希望对你有帮助。

来源: https://docs.python.org/2/faq/design.html

【讨论】:

你的问题倒过来了。这不是“如果它们被称为列表,为什么要使用数组来实现它们”;这是“如果它们是用数组实现的,为什么它们被称为列表”。 您的回答在谈到删除时也很混乱。你说删除是常数时间,然后你说它是摊销常数时间,但这些都不是真的。 那么你会如何描述从列表中删除一个元素的时间呢?如果我错了,你应该提供一些证据来帮助我理解。 按索引删除所花费的时间与必须移动以缩小差距的元素数量成正比;按值删除所花费的时间与列表的大小成正比,因为除了移动元素之外,Python 还需要找到要删除的元素。

以上是关于为啥 Python 列表在实现为动态数组时称为“列表”的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的数组列表即使在初始化后也会抛出空指针异常?

如何在Java中创建数组列表

为啥Visual Studio在声明字符串数组列表时会抛出异常

在 python 中,为啥从数组读取比从列表读取慢?

表 (python实现)

为啥 Intellij Idea 建议在使用循环将数组转换为 Set 时创建中间列表?