【问题标题】:Is using [::-1] in python to reverse a list O(1) space?在 python 中使用 [::-1] 来反转列表 O(1) 空间?
【发布时间】:2020-02-29 22:28:58
【问题描述】:

如果我写了:

item_list = item_list[::-1]

这会是 O(1) 空间吗?我认为 item_list[::-1] 会导致创建一个新列表,所以这可能是 O(n)。 item_list.reverse() 那么是在 python 中用 O(1) 空间反转的正确方法吗?

【问题讨论】:

  • 不,它会创建列表的副本,并且需要线性空间/时间
  • 我认为,reversed() 的复杂度为 O(1)。
  • @Olvin 当然可以,但如果你把它列出来就不行
  • @OlvinR​​oght:它是一个生成器。如果你在它上面使用list(..),你会复制一份,因此有 O(n) 空间。
  • @WillemVanOnsem 术语 nitpick,它返回一个迭代器,而不是一个生成器

标签: python python-3.x list time-complexity reverse


【解决方案1】:

你是对的,some_list[::-1] 创建了一个 new 列表,并且该列表将有 n 个“插槽”,因此需要 O(n) 内存。

此外,在 Python 的解释器 CPython [GitHub] 中,.reverse() 是在 O(1) 内存中完成的。事实上,如果我们查看reverse method [GitHub],我们会看到:

/*[clinic input]
list.reverse
Reverse *IN PLACE*.
[clinic start generated code]*/

static PyObject *
list_reverse_impl(PyListObject *self)
/*[clinic end generated code: output=482544fc451abea9 input=eefd4c3ae1bc9887]*/
{
    if (Py_SIZE(self) > 1)
        reverse_slice(self->ob_item, self->ob_item + Py_SIZE(self));
    Py_RETURN_NONE;
}

它因此调用了一个函数reverse_slice, and this is implemented as [GitHub]

/* Reverse a slice of a list in place, from lo up to (exclusive) hi. */
static void
reverse_slice(PyObject **lo, PyObject **hi)
{
    assert(lo && hi);

    --hi;
    while (lo < hi) {
        PyObject *t = *lo;
        *lo = *hi;
        *hi = t;
        ++lo;
        --hi;
    }
}

因此它与两个指针一起工作,一个以升序迭代,一个以降序迭代,并且这些“交换”值彼此,直到它们在中途相遇。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-24
    • 1970-01-01
    • 1970-01-01
    • 2020-01-28
    • 2016-08-25
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    相关资源
    最近更新 更多