有没有简单的方法将std::list<double>转换为Python列表?

2 投票
2 回答
530 浏览
提问于 2025-04-15 12:22

我正在用C/C++写一个小的Python扩展,里面有一个这样的函数:

void set_parameters(int first_param, std::list<double> param_list)
{
   //do stuff
}

我希望能够像这样从Python调用它:

set_parameters(f_param, [1.0, 0.5, 2.1])

有没有比较简单的方法来实现这个转换?理想情况下,我希望这个方法不需要太多额外的依赖,但有些事情确实需要额外的东西,所以这也不是特别大的问题。

2 个回答

0

你可以看看 Boost.Python。你问的问题在 迭代器 这一章里有讲解。

重点是,Boost.Python 提供了一个叫做 stl_input_iterator 的模板,它可以把 Python 的可迭代对象转换成 stl 的输入迭代器,这样你就可以用它来填充你的 std::list 了。

0

结果发现,这比我想象的要简单得多,尤其是在我找到那些我应该在提问之前就读过的文档之后。我在我的包装函数中得到了一个PyList对象,然后只需遍历它,把里面的值放到我需要的向量中。代码大概是这样的:

static PyObject* py_set_perlin_parameters(PyObject* self, PyObject* args)
{
    int octaves;
    double persistence;
    PyObject* zoom_list;
    int zoom_count = 0;
    std::vector<double> zoom_vector;

    if(!PyArg_ParseTuple(args, "idO!:set_perlin_parameters", &octaves, &persistence, &PyList_Type, &zoom_list))
    {
        return NULL;
    }

    if(!PyList_Check(zoom_list)) 
    {
        PyErr_SetString(PyExc_TypeError, "set_perlin_parameters: third parameter must be a list");
        return NULL;
    }

    zoom_count = PyList_Size(zoom_list);

    for(int i = 0; i < zoom_count; i++)
    {
        PyObject* list_val;
        double val;

        list_val = PyList_GetItem(zoom_list, i);

        if(list_val == NULL)
        {
            return NULL;
        }

        val = PyFloat_AsDouble(list_val);

        zoom_vector.push_back(val);
    }

    set_perlin_parameters(octaves, persistence, zoom_vector);

    return Py_None;
}

撰写回答