如何在 Python 中遍历 C++ 集?

Posted

技术标签:

【中文标题】如何在 Python 中遍历 C++ 集?【英文标题】:How to iterate throught C++ sets in Cython? 【发布时间】:2015-03-22 22:25:32 【问题描述】:

我正在使用 Cython 优化 python 代码。 C++ 中的一个集合存储了我所有的结果,我不知道如何访问数据以将其移动到 Python 对象中。结构必须是一个集合。我无法将其更改为矢量、列表等。

我知道如何在 Python 和 C++ 中执行此操作,但在 Cython 中不知道。如何在 Cython 中检索迭代器?我通过 libcpp.STLContainer 获取 STL 容器,如

来自 libcpp.vector cimport 向量

但是,我不知道迭代器在 Cython 中是如何工作的。我需要导入什么?而且,与在 C++ 中的工作方式相比,使用迭代器的语法是否有任何变化?

【问题讨论】:

C++类没有自己的迭代器吗? 是的,但我不知道如何调用它。我尝试了几件事,但都没有奏效。 set 类文件本身在类定义中定义了迭代器,但我不知道如何访问它。 此文档部分是否有用:docs.cython.org/src/userguide/… 【参考方案1】:

Cython 应该在需要时自动将 c++ 集转换为 python 集,但是如果您确实确实需要在 c++ 对象上使用迭代器,您也可以这样做。

如果我们举一个非常简单的例子,用 c++ 构造一个集合

libset.cc

#include <set>

std::set<int> make_set()

    return 1,2,3,4;

libset.h

#include <set>

std::set<int> make_set();

然后我们可以为此代码编写 cython 包装器,其中我给出了一个如何以一种很好的 Python 方式(在后台使用 c++ 迭代器)迭代集合的示例以及如何直接用迭代器来做。

pyset.pyx

from libcpp.set cimport set
from cython.operator cimport dereference as deref, preincrement as inc

cdef extern from "libset.h":
    cdef set[int] _make_set "make_set"()

def make_set():
    cdef set[int] cpp_set = _make_set()

    for i in cpp_set: #Iterate through the set as a c++ set
        print i

    #Iterate through the set using c++ iterators.
    cdef set[int].iterator it = cpp_set.begin()
    while it != cpp_set.end():
        print deref(it)
        inc(it)

    return cpp_set    #Automatically convert the c++ set into a python set

这可以用一个简单的 setup.py 编译

setup.py

from distutils.core import setup, Extension
from Cython.Build import cythonize

setup( ext_modules = cythonize(Extension(
            "pyset",
            sources=["pyset.pyx", "libset.cc"],
            extra_compile_args=["-std=c++11"],
            language="c++"
     )))

【讨论】:

【参考方案2】:

西蒙的回答非常好。我必须为 C++ 映射到 python dict 执行此操作。这是地图案例的粗略 cython 代码:

from libcpp.map cimport map

# code here for _make_map() etc.

def get_map():
    '''
    get_map()
    Example of cython interacting with C++ map.

    :returns: Converts C++ map<int, int> to python dict and returns the dict
    :rtype: dict
    '''
    cdef map[int, int] cpp_map = _make_map()

    pymap = 
    for it in cpp_map: #Iterate through the c++ map
        pymap[it.first] = it.second

    return pymap

【讨论】:

以上是关于如何在 Python 中遍历 C++ 集?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PowerShell 中遍历数据集?

如何在 C++ 中遍历 LPBYTE 的每个字节

如何在c++中遍历treeview控件的所有父节点?

C++遍历mysql结果集,一万条数据花多长时间?

C++如何遍历文件夹?

如何遍历 spark 数据集并更新 Java 中的列值?