How to iterate C ++ sets in Cython?

I am optimizing python code with Cython. A set in C ++ stores all my results, and I don’t know how to access data to move it to a Python object. The structure must be multitude. I cannot change it to a vector, list, etc.

I know how to do this in Python and C ++, but not in Cython. How are iterators retrieved in Keaton? I get STL containers via libcpp.STLContainer, as in

from libcpp.vector cimport vector

But I do not know how iterators work in Cython. What do I need to import? And are there any syntax changes for using iterators compared to how they work in C ++?

+6
source share
2 answers

Cython should automatically convert a C ++ set to a python set when necessary, however, if you really need to use iterators on a C ++ object, you can also do this.

If we make a very simple example, when we build a set in C ++

libset.cc

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

libset.h

 #include <set> std::set<int> make_set(); 

Then we can write a cython shell for this code, where I gave an example of how to iterate through a set in a good pythonic way (which uses C ++ iterators in the background) and an example of how to do it directly using iterators.

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 

This can then be compiled with a simple 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++" ))) 
+9
source

Simon’s very nice answer. I had to do this for a C ++ map for python dict. Here is my crude cython code for the map case:

 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 
+2
source

Source: https://habr.com/ru/post/984114/


All Articles