如何在 Python 中遍历 C++ 集?
How to iterate throught C++ sets in Cython?
我正在使用 Cython 优化 python 代码。 C++ 中的一个集合存储了我所有的结果,我不知道如何访问数据以将其移动到 Python 对象中。结构必须是一个集合。我无法将其更改为向量、列表等
我知道如何在 Python 和 C++ 中执行此操作,但在 Cython 中不知道。如何在 Cython 中检索迭代器?我通过 libcpp.STLContainer 获得 STL 容器,如
from libcpp.vector cimport vector
但是,我不知道迭代器在 Cython 中是如何工作的。我需要导入什么?而且,与迭代器在 C++ 中的工作方式相比,使用迭代器的语法有什么变化吗?
Cython 应该在需要时自动将 c++ 集转换为 python 集,但是如果你真的 do 需要在 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++"
)))
Simon 的回答非常好。我必须为 python dict 的 C++ 映射执行此操作。这是地图案例的粗略 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
我正在使用 Cython 优化 python 代码。 C++ 中的一个集合存储了我所有的结果,我不知道如何访问数据以将其移动到 Python 对象中。结构必须是一个集合。我无法将其更改为向量、列表等
我知道如何在 Python 和 C++ 中执行此操作,但在 Cython 中不知道。如何在 Cython 中检索迭代器?我通过 libcpp.STLContainer 获得 STL 容器,如
from libcpp.vector cimport vector
但是,我不知道迭代器在 Cython 中是如何工作的。我需要导入什么?而且,与迭代器在 C++ 中的工作方式相比,使用迭代器的语法有什么变化吗?
Cython 应该在需要时自动将 c++ 集转换为 python 集,但是如果你真的 do 需要在 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++"
)))
Simon 的回答非常好。我必须为 python dict 的 C++ 映射执行此操作。这是地图案例的粗略 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