Skip to content Skip to sidebar Skip to footer

How Iterate (key, Value) Boost::python:dict

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 ke

Solution 1:

You can simply loop over all key/value pairs as follows:

usingnamespace boost::python;

list items = MyBoostPythonDict.items();
for(ssize_t i = 0; i < len(items); ++i) {
    object key = items[i][0];
    object value = items[i][1];
    // ...
}

Now you need to extract the corresponding types from key and value. Assuming both are of type int you would use:

extract<int> key_int(key);
extract<int> value_int(value);

if (key_int.check() && value_int.check()) {
    cout << key_int << ": " << value_int << endl;
}

Solution 2:

Just use item list directly:

for (auto x : MyBoostPythonDict.items())

Im guessing the iteritems is probably intended to be used something like this:

for(auto it = D.iteritems(); it; ++it)

Solution 3:

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>usingnamespace 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<constchar*>(str(key)) << " : " << extract<constchar*>(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.

Post a Comment for "How Iterate (key, Value) Boost::python:dict"