我正在用Cython优化python代码。 C ++中的一个集合存储了我的所有结果,我不知道如何访问数据以将其移动到Python对象中。结构必须是一组。我无法将其更改为矢量,列表等。
我知道如何在Python和C ++中执行此操作,但不是在Cython中。如何在Cython中检索迭代器?我通过libcpp.STLContainer获取STL容器,如
来自libcpp.vector cimport vector
但是,我不知道迭代器在Cython中是如何工作的。我需要导入什么?并且,使用迭代器的语法与它们在C ++中的工作方式相比是否有任何变化?
答案 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