【问题标题】:Cython - Declare List from InputCython - 从输入声明列表
【发布时间】:2019-10-29 13:10:02
【问题描述】:

我正在尝试使用 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

【问题讨论】:

    标签: python c cython cythonize


    【解决方案1】:

    cdef object result[N] 有两个问题:

    1. 它创建了一个 Python 对象的 C 数组 - 这并不真正起作用,因为 C 数组不容易与 Python 对象引用计数集成(在这种情况下,您需要将整个数组复制到其他对象当你无论如何都返回它时,因为它是一个仅作用于函数的局部变量。

    2. 对于 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 调用,您可以从 cpython.list 调用 cimport。请参阅Cythonize list of all splits of a string 以获取类似的示例,其中以这种方式优化列表创建。 PyList_New 的优点是它会在开始时创建一个适当大小的列表,其中填充有 NULL 指针,然后您可以填写。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多