You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在C++中嵌入Python:如何解析Python函数返回的列表?

在C++中解析Python返回的嵌套浮点列表

你需要通过递归方式解析Python返回的嵌套列表,因为列表元素可能是子列表或浮点值。以下是完整的代码示例,将Python嵌套列表转换为C++的std::vector<std::vector<double>>:

完整代码实现

首先定义递归解析函数,再在你的调用逻辑中使用:

#include <vector>
#include <iostream>
#include <Python.h>

// 递归解析单层浮点列表(用于嵌套结构中的子列表)
bool ParseFloatList(PyObject* pList, std::vector<double>& outVec) {
    Py_ssize_t size = PyList_Size(pList);
    for (Py_ssize_t i = 0; i < size; ++i) {
        PyObject* pItem = PyList_GetItem(pList, i); // 借用引用,无需手动释放

        // 处理浮点值
        if (PyFloat_Check(pItem)) {
            outVec.push_back(PyFloat_AsDouble(pItem));
        }
        // 兼容Python整数(自动转为double)
        else if (PyLong_Check(pItem)) {
            outVec.push_back(static_cast<double>(PyLong_AsLongLong(pItem)));
        }
        // 遇到非预期类型,抛出错误
        else {
            PyErr_SetString(PyExc_TypeError, "List contains non-numeric value");
            return false;
        }
    }
    return true;
}

// 解析嵌套列表(外层列表的元素是子列表)
bool ParseNestedFloatList(PyObject* pNestedList, std::vector<std::vector<double>>& outNestedVec) {
    if (!PyList_Check(pNestedList)) {
        PyErr_SetString(PyExc_TypeError, "Expected nested list as return value");
        return false;
    }

    Py_ssize_t outerSize = PyList_Size(pNestedList);
    for (Py_ssize_t i = 0; i < outerSize; ++i) {
        PyObject* pSubList = PyList_GetItem(pNestedList, i);
        if (!PyList_Check(pSubList)) {
            PyErr_SetString(PyExc_TypeError, "Nested structure contains non-list element");
            return false;
        }

        std::vector<double> subVec;
        if (!ParseFloatList(pSubList, subVec)) {
            return false;
        }
        outNestedVec.push_back(subVec);
    }
    return true;
}

// 你的原有调用逻辑
int main() {
    // 初始化Python环境(必须添加)
    Py_Initialize();

    PyObject *pFunction, *pArguments, *pArgumentValue;
    // 假设你已经通过PyImport_ImportModule、PyObject_GetAttrString等获取了pFunction和pArguments

    pArgumentValue = PyObject_CallObject(pFunction, pArguments);
    Py_DECREF(pArguments);

    if (pArgumentValue != NULL) {
        // 解析嵌套列表
        std::vector<std::vector<double>> parsedData;
        if (ParseNestedFloatList(pArgumentValue, parsedData)) {
            // 解析成功,示例遍历输出数据
            std::cout << "Parsed nested list:\n";
            for (const auto& subList : parsedData) {
                for (double val : subList) {
                    std::cout << val << " ";
                }
                std::cout << "\n";
            }
        } else {
            PyErr_Print();
        }

        // 释放返回值的引用
        Py_DECREF(pArgumentValue);
    } else {
        PyErr_Print();
    }

    // 关闭Python环境
    Py_Finalize();
    return 0;
}

关键注意事项

  • 引用计数:PyList_GetItem返回的是借用的引用,无需手动调用Py_DECREF;但PyObject_CallObject返回的pArgumentValue是新引用,必须调用Py_DECREF释放。
  • 类型检查:必须先判断对象类型(PyList_Check、PyFloat_Check等),避免非法内存访问。
  • 错误处理:解析失败时通过PyErr_SetString设置Python错误,再用PyErr_Print输出错误信息。
  • 兼容性:代码兼容Python返回的整数类型,自动转为double,如果不需要可以去掉这部分判断。

内容的提问来源于stack exchange,提问作者robotanical

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 13:21:23