1

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.

ArmanHunanyan
  • 905
  • 3
  • 11
  • 24
  • Does this answer your question? [How iterate (key, value) boost::python:dict](https://stackoverflow.com/questions/58096040/how-iterate-key-value-boostpythondict) – DavidW Apr 10 '21 at 07:41
  • A second duplicate https://stackoverflow.com/questions/57114920/boost-python-3-iterate-over-dict – DavidW Apr 10 '21 at 07:42
  • 1
    Unfortunately, both solutions create an intermediate list from the iterator and then iterate the list. While this will work for small dicts, in my case I have pretty big ones so I need to avoid creating temporary list. – ArmanHunanyan Apr 10 '21 at 19:33
  • Yeah I did have get impression that there isn't really a great solution to this (which is a bit surprising since it's the sort of thing that boost is usually keen on, and they do seem to have wrapped it the other way around) – DavidW Apr 10 '21 at 19:42
  • Yes, that surprises me too. – ArmanHunanyan Apr 10 '21 at 19:54
  • There is actually a (reasonably) elegant way of doing it - I've [posted it on the other question](https://stackoverflow.com/a/67038962/4657412) just because I think it's helpful to have all the answers in one place. Hopefully it's (close to) what you're after. – DavidW Apr 10 '21 at 20:32
  • I tested it and it definitely what I was looking for. Thank you. I will close this question. – ArmanHunanyan Apr 10 '21 at 21:07

0 Answers0