How can I iterate in C++ over my boost::python:dict ? I need key and value in every loop round.
My try was this:
for (auto x : MyBoostPythonDict.iteritems())
{
// determine key
// determine value
// ...
}
I got this error: C3312 no callable 'end' function found for type 'boost::python::api::object'
Boost Python exposes some STL iterator wrappers in the "stl_iterator" header that let you go from begin to end like a normal C++ iteration:
https://www.boost.org/doc/libs/1_75_0/libs/python/doc/html/reference/high_level_components/boost_python_stl_iterator_hpp.html
For Python version 2 you can use d.items() or d.iteritems() depending on whether you want to iterate lazily or not. For Python version 3 has a slight problem - you'd expect items to be a lazy dict view, but instead Boost Python converts it to a list. Therefore, I've called .attr("items")() instead to bypass the in-build conversion thus getting a lazy wrapper. I've returned this object to Python just to confirm that it's the view rather than a list.
Calling stl_input_iterator<tuple>() gives you an iterator for a (Python) tuple object from which you can extract the key and the value.
#include <boost/python/dict.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/stl_iterator.hpp>
#include <boost/python/extract.hpp>
#include <boost/python/str.hpp>
#include <boost/python.hpp>
#include <iostream>
using namespace boost::python;
object print_dict_to_cout(dict d) {
auto items = d.attr("items")(); // just plain d.items or d.iteritems for Python 2!
for (auto it = stl_input_iterator<tuple>(items); it != stl_input_iterator<tuple>(); ++it) {
tuple kv = *it;
auto key = kv[0];
auto value = kv[1];
std::cout << extract<const char*>(str(key)) << " : " << extract<const char*>(str(value)) << std::endl;
}
return items;
}
BOOST_PYTHON_MODULE(iterdict)
{
def("print_dict_to_cout", print_dict_to_cout);
}
The advantage of doing it this way is that it's lazy, and doesn't create the intermediate list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With