C++ std::vector 到 boost::python::list

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6157409/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:34:11  来源:igfitidea点击:

std::vector to boost::python::list

c++boost-python

提问by mcot

I have a method in c++ that gets called from python and needs to return a python list object.

我在 C++ 中有一个从 python 调用的方法,需要返回一个 python 列表对象。

I have already created the method, and its attached to an exposed class and callable from python right now... (it returns void).

我已经创建了该方法,并将其附加到一个公开的类并且现在可以从 python 调用......(它返回 void)。

So the question is, how do I create a python list from this:

所以问题是,我如何从这里创建一个 python 列表:

std::vector<std::string> results;

std::vector<std::string> results;

I am not really understanding how the constructor works from this documentation:

我不太明白构造函数是如何从这个文档中工作的:

http://www.boost.org/doc/libs/1_37_0/libs/python/doc/v2/list.html

http://www.boost.org/doc/libs/1_37_0/libs/python/doc/v2/list.html

Also... I don't really want to return kind of wrapped vector... I just want to create a new python list with the string values from the vector.

另外......我真的不想返回某种包装的向量......我只想用向量中的字符串值创建一个新的python列表。

My apologies if this is a duplicate... I found quite a few list to vector questions but I couldn't find any about creating a new python list.

如果这是重复的,我很抱歉......我找到了很多矢量问题列表,但我找不到任何关于创建新 python 列表的内容。

I could expand this question to include some other questions like:

我可以扩展这个问题以包括其他一些问题,例如:

Creating a new python dictionary from a: std::map<std::string, std::string>and so on.

从 a: 创建一个新的 python 字典std::map<std::string, std::string>,依此类推。

采纳答案by rafak

I have this function using iterators to convert std::vectorto py::list:

我有这个函数使用迭代器转换std::vectorpy::list

namespace py = boost::python;

template<class T>
py::list std_vector_to_py_list(const std::vector<T>& v)
{
    py::object get_iter = py::iterator<std::vector<T> >();
    py::object iter = get_iter(v);
    py::list l(iter);
    return l;
}

回答by Aleksey Vitebskiy

boost::pythonalready includes functionality for wrapping vectors and maps. Here's sample code for vectors, as you can see both passing and returning lists is quite simple:

boost::python已经包括包装矢量和地图的功能。这是向量的示例代码,您可以看到传递和返回列表都非常简单:

// C++ code
typedef std::vector<std::string> MyList;
class MyClass {
  MyList myFuncGet();
  void myFuncSet(const Mylist& list);
  //       stuff
};

// Wrapper code

#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

using namespace boost::python;


BOOST_PYTHON_MODULE(mymodule)
{
    class_<MyList>("MyList")
        .def(vector_indexing_suite<MyList>() );

    class_<MyClass>("MyClass")
        .def("myFuncGet", &MyClass::myFuncGet)
        .def("myFuncSet", &MyClass::myFuncSet)
        ;
}

Maps are very similar to vectors and are described in this post: Boost::Python- possible to automatically convert from dict --> std::map?

映射与向量非常相似,并在这篇文章中进行了描述: Boost::Python-可能从字典自动转换 --> std::map?

Unfortunately boost::pythondoes not currently include facilities for wrapping lists. You can create the wrapper manually, but I'm out of time for this answer. I can post it today or tomorrow. I'd appreciate a new question about this particular problem, because the answer will be quite extensive and is probably outside of the scope of this post. I'd just avoid lists and use vectors instead.

不幸的是boost::python,目前不包括包装列表的设施。您可以手动创建包装器,但我没有时间回答这个问题。我可以今天或明天发布。我很感激关于这个特定问题的新问题,因为答案将非常广泛,并且可能超出了本文的范围。我只是避免使用列表并使用向量代替。

回答by eudoxos

If you only want to create python list manually (and have the function return py::list rather than vector), do it like this:

如果您只想手动创建 python 列表(并让函数返回 py::list 而不是向量),请这样做:

/* using namespace std; namespace py=boost::python;
   #define FOREACH BOOST_FOREACH
*/
vector<string> ss;
py::list ret;
FOREACH(const string& s, ss) ret.append(s);
return s;

For automatic conversions, define the converter for vector from python list to c++ and from c++ to python list -- I just wrote about that at Instantiating shared_ptr's in boost::python(the second part of the reply); that way, you get realy python lists.

对于自动转换,定义向量从 python 列表到 c++ 和从 c++ 到 python 列表的转换器—​​—我刚刚在 boost::python中的Instantiating shared_ptr's写了这个(回复的第二部分);这样,你就会得到真正的 Python 列表。

Another possibility for automatic conversion (which I have no experience with) is to use indexing_suite, which will wrap vector<string>as a special class in python, as a colleague mentioned here already.

自动转换的另一种可能性(我没有经验)是使用 indexing_suite,它将vector<string>作为 python 中的一个特殊类进行包装,正如这里已经提到的一位同事。

回答by o.z

From http://gist.github.com/octavifs/5362272:

来自http://gist.github.com/octavifs/5362272

// Converts a C++ vector to a python list
template <class T>
boost::python::list toPythonList(std::vector<T> vector) {
    typename std::vector<T>::iterator iter;
    boost::python::list list;
    for (iter = vector.begin(); iter != vector.end(); ++iter) {
        list.append(*iter);
    }
    return list;
}

回答by Validus Oculus

I use following utility functions to convert from/to stl containers. The trivial sum function illustrates how they are used. Also I found following opensource package which has quite a few conversion utilities: https://github.com/cctbx/cctbx_project/tree/master/scitbx/boost_python

我使用以下实用程序函数来转换 stl 容器。平凡的 sum 函数说明了它们是如何使用的。我还发现以下开源包有很多转换实用程序:https: //github.com/cctbx/cctbx_project/tree/master/scitbx/boost_python

#include <vector>
#include <boost/python.hpp>
#include <boost/python/object.hpp>
#include <boost/python/stl_iterator.hpp>

namespace bpy = boost::python;

namespace fm {

template <typename Container>
bpy::list stl2py(const Container& vec) {
  typedef typename Container::value_type T;
  bpy::list lst;
  std::for_each(vec.begin(), vec.end(), [&](const T& t) { lst.append(t); });
  return lst;
}

template <typename Container>
void py2stl(const bpy::list& lst, Container& vec) {
  typedef typename Container::value_type T;
  bpy::stl_input_iterator<T> beg(lst), end;
  std::for_each(beg, end, [&](const T& t) { vec.push_back(t); });
}

bpy::list sum(const bpy::list& lhs, const bpy::list& rhs) {
  std::vector<double> lhsv;
  py2stl(lhs, lhsv);

  std::vector<double> rhsv;
  py2stl(rhs, rhsv);

  std::vector<double> result(lhsv.size(), 0.0);
  for (int i = 0; i < lhsv.size(); ++i) {
    result[i] = lhsv[i] + rhsv[i];
  }
  return stl2py(result);
}

} // namespace fm

BOOST_PYTHON_MODULE(fm)
{
  bpy::def("sum", &fm::sum);
}

回答by Rob Agar

FWIW, here's a templated function in the same vein as eudoxos' solution:

FWIW,这是一个与eudoxos 解决方案相同的模板化函数:

namespace py = boost::python;

template<class T>
py::list std_vector_to_py_list(const std::vector<T>& v)
{
  py::list l;
  typename std::vector<T>::const_iterator it;
  for (it = v.begin(); it != v.end(); ++it)
    l.append(*it);   
  return l;  
}