2015-03-22 2 views
6

Я оптимизирую код python с Cython. Набор в C++ хранит все мои результаты, и я не знаю, как получить доступ к данным, чтобы переместить его в объект Python. Структура должна быть множеством. Я не могу изменить его на вектор, список и т. Д.Как перебрать все C++ наборы в Cython?

Я знаю, как это сделать в Python и C++, но не в Cython. Как итераторы извлекаются в Китоне? Я получаю STL контейнеров через libcpp.STLContainer как в

из libcpp.vector cimport вектора

Но, я не знаю, как итераторы работают в Cython. Что мне нужно импортировать? И есть ли какие-либо изменения в синтаксисе для использования итераторов по сравнению с тем, как они работают на C++?

+0

Не имеет ли на C++ класс своего итератора? – hpaulj

+0

Да, но я не знаю, как его вызывать. Я пробовал несколько вещей, и никто не работал. Сам набор файлов классов определяет итератор в определении класса, но я не знаю, как его получить. – ReverseFlow

+0

Является ли эта секция доктором для любого использования: http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html#standard-library – hpaulj

ответ

9

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 для этого кода, где я привел пример того, как итерации через набор в хороший питонический путь (который использует итераторы 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 
Смежные вопросы