我正在尝试使用cython将对象列表(GeoJSON)转换为整齐的对象,但是我遇到了错误:
这段代码似乎是问题:cdef object result[N]
。如何从给定的list
中声明列表/数组?
这是我当前的代码:
def convert_geoms(list array):
cdef int i, N=len(array)
cdef double x, s=0.0
cdef object result[N] # ERROR HERE
for i in range(N):
g = build_geometry_objects2(array[i])
result[i] = g
return result
cdef object result[N]
有两个问题:
它创建一个Python对象的C数组-这实际上不起作用,因为C数组不容易与Python对象引用计数集成(在这种情况下,您需要将整个数组复制到其他对象上无论如何都返回了它,因为它是一个局部变量,仅作用于该函数)。
对于格式为sometype result[N]
的C数组,必须在编译时知道N
。在这种情况下,每个函数调用的N
是不同的,因此变量定义仍然无效。
有多种解决方案-大多数解决方案仅涉及接受您正在使用Python对象,因此不必担心指定类型并只编写有效的Python代码。我可能会将其写为列表理解。我怀疑Cython在为此生成优化代码方面会出奇的出色]
return [ build_geometry_objects2(array[i]) for i in range(len(array)) ]
# or
return [ build_geometry_objects2(a) for a in array ]
第二个版本可能更好,但是如果有问题,您可以安排时间。
如果性能确实很重要,则可以使用Python C API调用,您可以从cimport
中进行cpython.list
。有关以这种方式优化列表创建的类似示例,请参见Cythonize list of all splits of a string。 PyList_New
的优点在于,它会在开始时创建一个适当大小的列表,并填充NULL
指针,然后您就可以填写。