Home > database >  Cython: How to sort vector with closure
Cython: How to sort vector with closure

Time:11-05

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
  • Related