如何在Cython中遍历C++的set?

10

我正在使用Cython优化Python代码。一个C++中的set存储了所有的结果,但我不知道如何访问数据以将其移入Python对象。结构必须是一个set,不能改为vector、list等。

我知道如何在Python和C++中操作,但不知道如何在Cython中进行。在Cython中如何获取迭代器?我通过以下方式获得STL容器:

from libcpp.vector cimport vector

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


C++类没有自己的迭代器吗? - hpaulj
是的,但我不知道如何调用它。我尝试了几种方法,但都没有成功。set类文件本身在类定义中定义了迭代器,但我不知道如何访问它。 - ReverseFlow
这个文档章节有用吗:http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html#standard-library - hpaulj
2个回答

16
Cython应在需要时自动将C++ set转换为Python set,但是如果您确实需要在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包装器来调用此代码。下面是一个示例,展示了如何以Pythonic的方式迭代集合(在后台使用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++"
     )))

3

Simon的回答非常好。我需要将C++ map转换为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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接