2015-03-22 16 views
6

Tôi đang tối ưu hóa mã python bằng Cython. Một bộ trong C++ lưu trữ tất cả các kết quả của tôi, và tôi không biết cách truy cập dữ liệu để di chuyển nó vào một đối tượng Python. Cấu trúc phải là một tập hợp. Tôi không thể thay đổi thành vectơ, danh sách, v.v.Làm thế nào để lặp qua bộ C++ trong Cython?

Tôi biết cách thực hiện điều này bằng Python và C++, nhưng không phải trong Cython. Các trình vòng lặp được truy xuất trong Cython như thế nào? Tôi nhận được STL container qua libcpp.STLContainer như trong

từ vector libcpp.vector cimport

Nhưng, tôi không biết làm thế nào lặp làm việc trong Cython. Tôi cần nhập gì? Và, có bất kỳ thay đổi nào về cú pháp khi sử dụng các trình vòng lặp hay không so với cách chúng hoạt động trong C++?

+0

Lớp C++ có trình lặp riêng không? – hpaulj

+0

Có, nhưng tôi không biết cách gọi nó. Tôi đã thử nhiều thứ và không làm việc gì cả. Bản thân tập tin lớp đã định nghĩa định nghĩa vòng lặp trong định nghĩa lớp, nhưng tôi không biết cách truy cập nó. – ReverseFlow

+0

Phần tài liệu này có sử dụng bất kỳ: http://docs.cython.org/src/userguide/wrapping_CPlusPlus.html#standard-library – hpaulj

Trả lời

9

Cython sẽ tự động chuyển đổi bộ C++ thành bộ python khi cần, tuy nhiên nếu bạn thực sự làm cần sử dụng trình lặp trên đối tượng C++ bạn cũng có thể thực hiện điều đó.

Nếu chúng ta thực hiện một ví dụ rất đơn giản mà chúng ta xây dựng một tập trong C++

libset.cc

#include <set> 

std::set<int> make_set() 
{ 
    return {1,2,3,4}; 
} 

libset.h

#include <set> 

std::set<int> make_set(); 

Sau đó chúng tôi có thể viết trình bao bọc cython cho mã này là, nơi tôi đã đưa ra một ví dụ về cách lặp qua tập hợp trong một nic cách e ththonic (sử dụng các trình lặp C++ trong nền) và một ví dụ về cách thực hiện nó trực tiếp với các trình vòng lặp.

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 

này sau đó có thể được biên dịch với một setup.py đơn giản

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âu trả lời rất đẹp bởi Simon. Tôi đã phải làm điều này cho một bản đồ C + + để python dict. Đây là mã cython thô của tôi cho trường hợp bản đồ:

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 
Các vấn đề liên quan