繁体   English   中英

在 CPython 中实现的实际“排序”方法在哪里,它在这里做什么?

[英]Where is the actual "sorted" method being implemented in CPython and what is it doing here?

在GitHub上查看CPython的源码,看到这里的方法:
https://github.com/python/cpython/blob/main/Python/bltinmodule.c

更具体地说:

static PyObject *
builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
    PyObject *newlist, *v, *seq, *callable;

    /* Keyword arguments are passed through list.sort() which will check
       them. */
    if (!_PyArg_UnpackStack(args, nargs, "sorted", 1, 1, &seq))
        return NULL;

    newlist = PySequence_List(seq);
    if (newlist == NULL)
        return NULL;

    callable = _PyObject_GetAttrId(newlist, &PyId_sort);
    if (callable == NULL) {
        Py_DECREF(newlist);
        return NULL;
    }

    assert(nargs >= 1);
    v = _PyObject_FastCallKeywords(callable, args + 1, nargs - 1, kwnames);
    Py_DECREF(callable);
    if (v == NULL) {
        Py_DECREF(newlist);
        return NULL;
    }
    Py_DECREF(v);
    return newlist;
}

我不是 C 大师,但我没有看到任何已知排序算法的任何实现,更不用说 Python 使用的特殊排序(我认为它叫做 Timsort? - 如果我错了请纠正我)

如果你能帮助我“消化”这段代码并理解它,我将不胜感激,因为截至目前我已经:

PyObject *newlist, *v, *seq, *callable;

哪个正在创建一个新列表——即使列表是可变的? 那为什么要创建一个新的?
并创建一些其他指针,不知道为什么......

然后我们按照评论的建议解压 arguments 的 rest,如果它与那里的 arguments 不匹配(例如 function“排序”),那么我们就会爆发......

我很确定我读的这一切完全错了,所以我停在这里......

感谢高级帮助,对于多个问题感到抱歉,但是这段代码让我大吃一惊,学习阅读它会对我有很大帮助!

实际排序由list.sort完成。 sorted只是根据给定的任何可迭代参数创建一个新列表,就地对该列表进行排序,然后返回它。 sorted的纯 Python 实现可能看起来像

def sorted(itr, *, key=None):
    newlist = list(itr)
    newlist.sort(key=key)
    return newlist

大多数 C 代码只是用于处理底层 C 数据结构、检测和传播错误以及进行 memory 管理的样板。

实际的排序算法遍及 Objects/listobject.c; 这里开始。 如果你真的对算法是什么感兴趣,而不是它在 C 中是如何实现的,你可能想从https://github.com/python/cpython/blob/main/Objects/listsort.txt开始。

列表排序实现不存在。 这是一个包装器PyId_sort从那里获取 PyId_sort:

callable = _PyObject_GetAttrId(newlist, &PyId_sort);

object.h包含一个使用标记粘贴来定义PyId_xxx对象的宏

#define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname)

...然后我就停止挖掘了。 为了在整个 python 代码库中强制执行连贯的命名,可能会涉及更多的宏魔法。

实施位于此处:

https://github.com/python/cpython/blob/main/Objects/listobject.c

更准确地说是在 2240 行附近

static PyObject *
list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
/*[clinic end generated code: output=57b9f9c5e23fbe42 input=cb56cd179a713060]*/
{

评论阅读:

/* An adaptive, stable, natural mergesort.  See listsort.txt.
 * Returns Py_None on success, NULL on error.  Even in case of error, the
 * list will be some permutation of its input state (nothing is lost or
 * duplicated).
 */

现在需要一些努力来理解算法的细节,但它就在那里。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM