如何将2D Python列表转换为2D C++向量?

2024-10-05 11:33:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我给了我的函数一个2D Python列表,并想把它转换成2D C++向量。但我不明白我怎么能做到。输入是n维坐标点的列表。每个坐标点本身就是一个列表。单个点值是双精度的。这是我目前的代码:

PyObject* foo(PyObject* self, PyObject* args) {
    PyObject* polyList;
    // Verify that argument is a list
    if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &polyList)) {
        return NULL;
    }
    std::vector<std::vector<double>> poly;
    // for each elem in list
    for (unsigned int i = 0; i < PyList_Size(polyList); ++i) {
        PyObject* pypoint = PyList_GetItem(polyList, i);
        std::vector<double> point;
        // Verify that elem is a list (coord point)
        if (!PyArg_ParseTuple(pypoint, "O!", &PyList_Type, &pypoint)) {
            PyErr_SetString(PyExc_TypeError, "must pass in list of list");
            return NULL;
        }
        for (unsigned int j = 0; j < PyList_Size(pypoint); ++i) {
            PyObject* coord = PyList_GetItem(pypoint, j);
            double val;
            // Verify that coord is a double
            if (!PyArg_ParseTuple(coord, "d", &val)) {
                PyErr_SetString(PyExc_TypeError, "must pass in list of list of number");
                return NULL;
            }
            point.push_back(val);
        }
        poly.push_back(point);
    }
    //...
}

当我传递一个像[[1.0, 1.0], [2.5, 3.7]]这样的2d列表时,我会得到一个错误提示,我必须传递一个列表列表。所以我猜错误在if (!PyArg_ParseTuple(pypoint, "O!", &PyList_Type, &pypoint)) {行的某个地方。但是pypoint如果不是一个列表,那是什么呢?使用cout << Py_TYPE(pypoint)我得到了66577D20,但这并没有告诉我任何事情

我在这里读到另一篇文章,可能是因为Python列表是指针列表,但这仍然没有告诉我如何进行转换


Tags: 列表ifthatislistpointpyobjectdouble
1条回答
网友
1楼 · 发布于 2024-10-05 11:33:35

多亏了@YiFei,我研究了PyList_Check和其他Py_Check函数,找到了一个可行的解决方案。代码如下:

PyObject* foo(PyObject* self, PyObject* args) {
    PyObject* polyList;
    // Verify that argument is a list
    if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &polyList)) {
        return NULL;
    }
    std::vector<std::vector<double>> poly;
    for (int i = 0; i < PyList_Size(polyList); ++i) {
        PyObject* pypoint = PyList_GetItem(polyList, i);
        std::vector<double> point;
        // Verify that each pypoint also a list
        if (!PyList_Check(pypoint)) {
            PyErr_SetString(PyExc_TypeError, "must pass in list of list");
            return NULL;
        }
        for (int j = 0; j < PyList_Size(pypoint); ++j) {
            PyObject* coord = PyList_GetItem(pypoint, j);
            double val;
            // Check that each coord is a long/double
            if (PyLong_Check(coord)) {
                val = (double) PyLong_AsLong(coord);
            } else if (PyFloat_Check(coord)) {
                val = PyFloat_AsDouble(coord);
            } else {
                PyErr_SetString(PyExc_TypeError, "must pass in list of list of number");
                return NULL;
            }
            point.push_back(val);
        }
        poly.push_back(point);
    }
    //...
}

当然,可以使用任何其他检查替换以下行,以将非长/双精度值的二维列表转换为二维向量

// Check that each coord is a long/double
if (PyLong_Check(coord)) {
    val = (double) PyLong_AsLong(coord);
} else if (PyFloat_Check(coord)) {
    val = PyFloat_AsDouble(coord);
} else {
    PyErr_SetString(PyExc_TypeError, "must pass in list of list of number");
    return NULL;
}

有关所需类型的特定Py_检查函数,请参见https://docs.python.org/3/c-api/concrete.html

它可能不是最优化的解决方案,但它是有效的

相关问题 更多 >

    热门问题