【问题标题】:Why is a sorted list bigger than an unsorted list为什么排序列表比未排序列表大
【发布时间】:2017-03-11 23:15:11
【问题描述】:

我有一个列表my_list(该列表包含utf8字符串):

>>> len(my_list)
8777
>>> getsizeof(my_list)                     #  <-- note the size
77848

由于某种原因,排序列表 (my_sorted_list = sorted(my_list)) 使用更多内存:

>>> len(my_sorted_list)
8777
>>> getsizeof(my_sorted_list)              #  <-- note the size
79104

为什么sorted 返回的列表比初始未排序列表占用更多内存空间?

【问题讨论】:

标签: python list python-3.x sorting python-internals


【解决方案1】:

作为Ignacio points out,这是由于 Python 分配的内存比所需的多。这样做是为了在列表上执行 O(1) .appends

sorted creates a new list 在提供的序列之外,sorts it in place 并返回它。要创建新列表,Python extends an empty sized list with the one passed;这导致观察到的过度分配(在调用list_resize 之后发生)。您可以使用list.sort 来证实排序不是罪魁祸首的事实; 使用相同的算法,无需创建新列表(或者,众所周知,它是就地执行)。当然,那里的尺寸没有区别

值得注意的是,这种差异主要存在于以下情况:

因此,使用列表组合:

l = [i for i in range(10)]

getsizeof(l)          # 192
getsizeof(sorted(l))  # 200

或列表文字:

l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

getsizeof(l)          # 144
getsizeof(sorted(l))  # 200

尺寸更小(使用文字更是如此)。

通过list创建时,内存总是过度分配; Python knows the sizes 并通过根据大小过度分配位来抢占未来的修改:

l = list(range(10))

getsizeof(l)          # 200
getsizeof(sorted(l))  # 200

因此您没有观察到列表大小的差异。


作为最后一点,我必须指出这是行为特定 Python 的C 实现,即 CPython。这是该语言如何实现的详细信息,因此,您不应该以任何古怪的方式依赖它。

Jython、IronPython、PyPy 和任何其他实现可能/可能不具有相同的行为。

【讨论】:

    【解决方案2】:

    list resize operation 过度分配是为了摊销附加到列表而不是从编译器预分配的列表开始。

    【讨论】:

    • 感谢 Python 代码的链接!太棒了……我会接受的,但@Jim 回答中的细节让我信服了。
    猜你喜欢
    • 2014-02-25
    • 2018-08-30
    • 2012-08-23
    • 2012-07-25
    • 2010-11-01
    • 1970-01-01
    • 2018-09-22
    相关资源
    最近更新 更多