のんびりしているエンジニアの日記

ソフトウェアなどのエンジニア的な何かを書きます。

Boost::python(3) pythonの辞書型(dict)、listで返す方法

Sponsored Links

皆さんこんにちわ
お元気ですか?

さて、本日もBoostしようか。
本日はlistとdictについて

さて、実はboost::pythonvectorとかmapではなく、pythonの型に直して返すことができます。
こいつらです。

>>> a = [1,2,3,4] #list
>>> b = {"foo","bar"} #dictionary

さて、早速やってみましょう。

辞書型

C++

#include <vector>
#include <map>
#include <boost/python.hpp>

using namespace std;

template<class T1,class T2>
boost::python::dict get_dict(map<T1,T2> &map_){  
     boost::python::dict py_dict;
     typename map<T1,T2>::const_iterator it;

     for(it = map_.begin(); it != map_.end(); ++it)   
          py_dict[it->first]=it->second;        
     return py_dict;  
}

boost::python::dict test(){
	map<string,string> mp;
	mp["foo"] = "bar";
	mp["temp"] = "tenp2";
	boost::python::dict return_dict;
	return_dict = get_dict(mp);
	return return_dict;
}

BOOST_PYTHON_MODULE(python_list){
	def("test", &test);
}

boost::python::dict型で返してあげれば、どうやらPythonで扱えるようです。
途中は
typename map::const_iterator it;
と指定せずに、
for(map::const_iterator it = map_.begin(); it != map_.end(); ++it)
と書くと以下のようなコンパイルエラーを吐きます。コンパイル時に型わかんねーよってことだろうか。
出たとき泣くかと思った。

python_list.cpp:12:10: error: missing 'typename' prior to dependent type name 'map<T1, T2>::const_iterator'
     for(map<T1,T2>::const_iterator it = map_.begin(); it != map_.end(); ++it)  

Python

>>> import python_dict
>>> dict = python_dict.test()
>>> dict
{'foo': 'bar', 'temp': 'tenp2'}
>>> dict["foo"]
'bar'

List

C++

#include <vector>
#include <map>
#include <boost/python.hpp>

using namespace std;

template<class T>
boost::python::list get_vect(vector<T> &list_){  
     boost::python::list py_list;
     typename vector<T>::const_iterator it;

     for(it = list_.begin(); it != list_.end(); ++it)   
          py_list.append(*it);
     return py_list;
}

boost::python::list test(){
	vector<int> vect;
	vect.push_back(2);
	vect.push_back(3);

	boost::python::list return_list;
	return_list = get_vect(vect);
	return return_list;
}

BOOST_PYTHON_MODULE(python_list){
	def("test", &test);
}

boost::pythonでもappend使えるんだね…。
templateがあれば十分使いやすいかな。

>>> import python_list
>>> python_list.test()
[2, 3]

boostそれは君の人生をも加速させる。
…もうこのネタいいかなぁ