如何在Python中迭代C ++集?

时间:2015-03-22 22:25:32

标签: c++ python-2.7 cython

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

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

  

来自libcpp.vector cimport vector

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

2 个答案:

答案 0 :(得分:11)

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包装器,其中我给出了一个如何以一种漂亮的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++"
     )))

答案 1 :(得分: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