【问题标题】:How iterate (key, value) boost::python:dict如何迭代 (key, value) boost::python:dict
【发布时间】:2020-01-25 12:10:12
【问题描述】:

如何在 boost::python:dict 上迭代 C++ ? 我在每个循环中都需要 keyvalue

我的尝试是这样的:

for (auto x : MyBoostPythonDict.iteritems())
{
    // determine key
    // determine value 
    // ...
}

我收到了这个错误: C3312 找不到类型“boost::python::api::object”的可调用“结束”函数

【问题讨论】:

标签: python c++ python-2.7 boost


【解决方案1】:

您可以简单地循环所有键/值对,如下所示:

using namespace 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];
    // ...
}

现在您需要从keyvalue 中提取相应的类型。假设两者都是 int 类型,您将使用:

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

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

【讨论】:

    【解决方案2】:

    直接使用项目列表即可:

    for (auto x : MyBoostPythonDict.items())
    

    我猜iteritems 可能打算这样使用:

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

    【讨论】:

    • 感谢您的回答。他对 "++it" 或 "it++" 有问题: --> 'boost::python::api::object' 没有定义此运算符或转换为预定义运算符可接受的类型
    • @bobmorane 直接使用items() 怎么样?
    • 直接是什么意思?
    • @bobmorane 如果您能提供一个最小且完整的示例,我可以改进答案。
    • @bobmorane 重点是:我不应该自己编写示例来帮助您 - 您可以轻松提供。见stackoverflow.com/help/minimal-reproducible-example
    【解决方案3】:

    Boost Python 在“stl_iterator”标头中公开了一些 STL 迭代器包装器,可让您像普通 C++ 迭代一样从 begin 转到 end

    https://www.boost.org/doc/libs/1_75_0/libs/python/doc/html/reference/high_level_components/boost_python_stl_iterator_hpp.html

    对于 Python 版本 2,您可以使用 d.items()d.iteritems(),具体取决于您是否要进行惰性迭代。对于 Python 版本 3 有一个小问题 - 您希望 items 是一个懒惰的 dict 视图,但 Boost Python 将其转换为列表。因此,我调用了.attr("items")() 来绕过内置转换,从而得到一个惰性包装器。我已将此对象返回给 Python,只是为了确认它是视图而不是列表。

    调用 stl_input_iterator&lt;tuple&gt;() 会为您提供一个 (Python) 元组对象的迭代器,您可以从中提取键和值。

    #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);
    }
    

    这样做的好处是它很懒,并且不会创建中间列表。

    【讨论】:

      猜你喜欢
      • 2021-02-16
      • 2016-01-11
      • 2017-02-01
      • 2014-10-10
      • 1970-01-01
      • 1970-01-01
      • 2015-03-22
      • 2015-01-18
      • 1970-01-01
      相关资源
      最近更新 更多