Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pybind11, convert std::vector to py::list

Tags:

pybind11

According to the pybind11 documentation https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html:

When including the additional header file pybind11/stl.h, conversions between std::vector<>/std::list<>/std::array<>, std::set<>/std::unordered_set<>, and std::map<>/std::unordered_map<> and the Python list, set and dict data structures are automatically enabled.

However, I cannot for the life of me get this to work. I suppose I am misunderstanding something, so I hope someone can clear it up for me.

Here is what I expected to work:

// Test
std::vector<double> test_vec{1,2,3,4,5};
py::list test_list = test_vec;
py::list test_list2(test_vec);
py::list test_list3 = py::cast<py::list>(test_vec);

And here are the errors:

error: conversion from ‘std::vector<double>’ to non-scalar type ‘pybind11::list’ requested
    py::list test_list = test_vec;
error: no matching function for call to ‘pybind11::list::list(std::vector<double>&)’
    py::list test_list2(test_vec);
error: no matching function for call to ‘cast(std::vector<double>&)’
    py::list test_list3 = py::cast<py::list>(test_vec)

The docs say to look in tests/test_stl.cpp for examples of how this should work, however I'm afraid that I am having trouble deciphering what is happening in that file.

like image 761
Ben Farmer Avatar asked Dec 11 '18 12:12

Ben Farmer


1 Answers

The conversion happens automatically for function arguments and return values that you create bindings for if you include pybind11/stl.h. You can also do it explicitly in C++ code like this:

#include <pybind11/stl.h>
// [...]
std::vector<double> test_vec{1, 2, 3, 4, 5};
py::list test_list3 = py::cast(test_vec);

Please bear in mind that this creates a copy, though.
For a different approach please refer to making-opaque-types and binding-stl-containers.

like image 132
ahans Avatar answered Oct 20 '22 23:10

ahans