I'm using latest Cython with C 17 flag (above C 11 to have closure syntax) to GCC. This C sort in Cython doesn't seem allowing closure:
# File: myfunc.pyx
from libcpp.vector cimport vector
from libcpp.algorithm cimport sort
# cpdef to call from Python, it just wraps cdef anyway
cpdef myfunc():
# int is just example, I need to sort struct vector
cdef vector[int] v
v.push_back(2)
v.push_back(1)
# Compile error: Expected ')', found 'a'
sort(v.begin(),v.end(), [](int a,int b){
return a<b
})
Is Cython supporting C closure and how to use it? How to do C sort with closure coz I'm porting Python to Cython and there are a lot of lambda sorts.
CodePudding user response:
In this case you don't actually need a "closure" - you don't capture any variables from the surrounding scope. Therefore for your particular example you could use a cdef
function (which must be defined at the global scope):
cdef bool compare(double a, double b):
return a<b
sort(v.begin(),v.end(), compare)
That obviously isn't a general solution. But a lot of the time passing a pointer to a C function really is all you need.
CodePudding user response:
I've tried to search and alter the code but these are the only ways:
- Use .hpp header
- Or use 'sorted' function of Python
Use .hpp header (.h is OK too if not using C feaures)
No C closure syntax in Cython as per my internet search, use struct with operator overload instead.
# File: mycmp.hpp
struct cmp {
bool operator()(int a,int b){ return a<b; }
};
# File: myfunc.pyx
cdef extern from "mycmp.hpp":
cdef struct cmp:
bool "operator()"(int a,int b)
cdef vector[int] v
v.push_back(2)
v.push_back(1)
cdef cmp compare
sort(v.begin(),v.end(), compare)
print(v)
Use 'sorted' function of Python
Because the .sort
is not on vector
, use sorted
function instead. This is much simpler but for other kinds of lambda, maybe not applicable
v = sorted(v, key=lambda x: x) # x or some prop of x