I am looking for a way to iterate through python dict (without creating tmp list object). After some little research I came to this.
boost::python::object dictItemsView(const boost::python::dict& dict)
{
#if PY_MAJOR_VERSION >= 3
return dict.items();
#else
return dict.iteritems();
#endif
}
template <typename Func>
void iterDict(const boost::python::dict& dict, Func func)
{
boost::python::handle<> iterH(boost::python::allow_null<>(PyObject_GetIter(dictItemsView(dict).ptr())));
if (!iterH.get()) {
PyErr_Clear();
return;
}
boost::python::object iter(iterH);
for (;;) {
boost::python::handle<> handle(boost::python::allow_null<>(PyIter_Next(iter.ptr())));
if (PyErr_Occurred()) {
assert(false);
PyErr_Clear();
return;
}
if (!handle.get()) break; // end of iteration
boost::python::object curr(handle);
func(curr);
}
}
Code is fully functional however I wonder how in such a well-designed library there is no shortcut for this.
There are a couple of solutions in StackOverflow suggesting to create a temporary list and iterate it. For performance reasons I need to avoid this.