How to convert python array to cython array? How to convert python array to cython array? arrays arrays

How to convert python array to cython array?


I believe you can do this by iterating over the python list of floats and putting them in a C array.

cimport cythonfrom libc.stdlib cimport malloc, freecdef:    float * cfloats    int icfloats = <float *> malloc(len(pyfloats)*cython.sizeof(float))if cfloats is NULL:  raise MemoryError()for i in xrange(len(pyfloats)):  cfloats[i] = pyfloats[i]setOverlays(cfloats)free(cfloats)


The accepted answer is wrong and leads to a segmentation fault, because the memory for the float * is never allocated.

The answer of @JAB shows the way to go, but I would like to elaborate more.

Passing an array:

The question is how to convert python array to an c-style array. Python array (from the array module) is a wrapper around continuous memory, so there is no need to copy the memory - we just can pass the pointer to the c-function:

from cpython cimport arrayimport arraydef set_overlays(array.array verts):    setOverlays(verts.data.as_floats)

Using array module is better than numpy because it is part of the standard library - there is no need to install something. This solution is short and nice, but has a problem: somebody could use it with an int-array and there will be no error - the memory just gets reinterpreted. Sometimes it is what one wants, but most of the time this is not the case.

To make sure, that the passed array-object has the right type of data, memory views can be used:

from cpython cimport array #still neededdef set_overlays_memview(float[::1] verts):    setOverlays(&verts[0])

[::1] ensures, that the memory view wraps around continuous memory. However, this code has a problem if there are no elements in the memory view,because of the out-of-bounds-access verts[0]. The right way to handle it depends on the function setOverlays and is not a part of this answer.

Passing a list:

If we have to pass a python list to the c-function, we have to copy the values to a continuous memory. Best done using the functionality of array- there is no need to reinvent the wheel:

from cpython cimport arrayimport arraydef set_overlays_list(list verts):    cdef array.array a =  array.array('f', verts)    setOverlays(a.data.as_floats) #we already know they are floats


Check out http://docs.cython.org/src/userguide/memoryviews.html. Looks like it also gives tips on how to utilize Python's built-in array module, as well as numpy.