【问题标题】:Develop a C module for applying selection sort开发用于应用选择排序的 C 模块
【发布时间】:2021-12-21 20:50:33
【问题描述】:

我正在尝试开发一个 C 模块,用于将选择排序算法应用于数据列表并将排序后的列表作为 Python 列表格式返回给 Python 程序。

但是,我发现下面程序的结果会是这样的 [431863472]

#include <Python.h>

int sorting(int n[])
{
    for (int i=0; i < sizeof(n)-1; i++){
        int minpos = i;
        for (int j=0; j < sizeof(n)-1; j++){
            if (n[j] < n[minpos]){
                minpos = j;
            }
        int temp = n[i];
        n[i] = n[minpos];
        n[minpos] = temp;  
        }
    }
    return n;
}

static PyObject* selectSort(PyObject* self, PyObject* args)
{
    // instantiate our `n` value
    int n[20000];
    // if our `n` value
    if(!PyArg_ParseTuple(args, "O", &n))
        return NULL;
    return Py_BuildValue("[i]", sorting(n));
}

static PyMethodDef myMethods[] = {
    { "selectSort", selectSort, METH_VARARGS, "Applying selection sort" },
    { NULL, NULL, 0, NULL }
};

static struct PyModuleDef myModule = {
    PyModuleDef_HEAD_INIT,
    "myModule",
    "Test Module",
    -1,
    myMethods
};

PyMODINIT_FUNC PyInit_myModule(void)
{
    return PyModule_Create(&myModule);
}

是不是把数组传给python的问题?或者我不应该使用“O”或“[i]”?

【问题讨论】:

  • 您所显示的内容本身不会产生任何输出。您肯定是从 Python 调用此代码吗?请出示minimal reproducible example
  • 相信您需要在 return 语句中使用 [iiii](列表中每个元素的 i)。也许this answer 会有所帮助。
  • int sorting(int n[]) 返回一个整数,因此[i] 是正确的(但当然不是所需的行为)
  • @DavidW - 声明肯定声明sorting 返回单个int,但是n 被初始化为20000 的数组大小,并且n 在整个函数中都被索引。看来该函数旨在返回数组(尽管在 C 中不可能)。除非指针被返回?
  • 这段代码有很多错误。你编译的时候不会收到一堆警告吗?

标签: python python-c-api


【解决方案1】:

这是一种可能的解决方案。请注意 PyArg_ParseTuple 如何使 argument 包含指向 Python 对象的链接。然后我检查这实际上是一个列表。这些值从 Python 整数对象转换为整数并复制到本地数组,该数组传递给 select_sort。排序后,将使用结果创建一个新的 Python 列表,并将其返回。

解决方案并不完美。例如,我不检查列表的所有元素是否都是整数。

#include <Python.h>

void select_sort(int count, int *values)
{
    for (int i = 0; i < count; i++)
    {
        int minpos = i;
        for (int j = 0; j < count; j++)
        {
            if (values[j] < values[minpos])
            {
                minpos = j;
            }

            int temp = values[i];
            values[i] = values[minpos];
            values[minpos] = temp;
        }
    }
}

#define MAX_LENGTH 20000

static PyObject *py_select_sort(PyObject *self, PyObject *args)
{
    PyObject *argument;

    // Get first object from tuple
    if (!PyArg_ParseTuple(args, "O", &argument))
    {
        return NULL;
    }

    // Is it a list?
    if (!PyList_Check(argument))
    {
        PyErr_SetString(PyExc_TypeError, "argument should be a list");
        return NULL;
    }

    // For simplicity we have a maximum size
    int length = PyList_Size(argument);
    if (length > MAX_LENGTH)
    {
        PyErr_SetString(PyExc_ValueError, "list is too big");
        return NULL;
    }

    // Local array to work with
    int values[MAX_LENGTH];

    // Copy values from Python list to local array
    for (int i = 0; i < length; i++)
    {
        values[i] = PyLong_AsLong(
            PyList_GetItem(argument, i)
        );
    }

    // Now sort!
    select_sort(length, values);

    // We'll return a new list
    PyObject *result = PyList_New(length);

    // Copy values back from local array to new Python list
    for (int i = 0; i < length; i++)
    {
        PyObject *value = PyLong_FromLong(values[i]);
        Py_IncRef(value);
        PyList_SetItem(result, i, value);
    }

    return result;
}

static PyMethodDef myMethods[] = {
    {"selectSort", py_select_sort, METH_VARARGS, "Applying selection sort"},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef myModule = {
    PyModuleDef_HEAD_INIT,
    "myModule",
    "Test Module",
    -1,
    myMethods
};

PyMODINIT_FUNC PyInit_myModule(void)
{
    return PyModule_Create(&myModule);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 2019-11-27
    相关资源
    最近更新 更多