我需要有一个python对象数组用于创建trie数据结构。我需要一个像元组一样固定长度的结构,像列表一样可变。我不想使用列表,因为我希望能够确保列表完全正确的大小(如果它开始分配额外的元素,内存开销可以非常快地加起来,因为特里增长更大)。有没有办法做到这一点?我尝试创建一个对象数组:
cdef class TrieNode:
cdef object members[32]
...但是这给了一个错误:
Error compiling Cython file:
------------------------------------------------------------
...
cdef class TrieNode:
cdef object members[32]
^
------------------------------------------------------------
/Users/jason/src/pysistence/source/pysistence/trie.pyx:2:23: Array element cannot be a Python object
做我想做的最好的方法是什么?
答案 0 :(得分:5)
我不知道最佳解决方案,但这里是 解决方案:
from cpython.ref cimport PyObject, Py_XINCREF, Py_XDECREF
DEF SIZE = 32
cdef class TrieNode:
cdef PyObject *members[SIZE]
def __cinit__(self):
cdef object temp_object
for i in range(SIZE):
temp_object = int(i)
# increment its refcount so it's not gc'd.
# We hold a reference to the object and are responsible for
# decref-ing it in __dealloc__.
Py_XINCREF(<PyObject*>temp_object)
self.members[i] = <PyObject*>temp_object
def __init__(self):
# just to show that it works...
for i in range(SIZE):
print <object>self.members[i]
def __dealloc__(self):
# make sure we decref the members elements.
for i in range(SIZE):
Py_XDECREF(self.members[i])
self.members[i] = NULL
Cython object
是自动重新计算的PyObject *
。只要您负责重新计算小虫子,您就可以随时滚动自己的PyObject *
数组。这可能是非平凡案件的一个主要问题。
答案 1 :(得分:1)
如果你只需要几个固定大小的这种结构,我会考虑制作统一名为__slots__
的类,包括一个size
槽来存储大小。您需要为每个大小(插槽数)声明一个单独的类。定义cdecl
函数以按索引访问插槽。访问性能可能不如C阵列的普通地址算术那么好,但是你可以确定只有那么多的插槽而且没有更多。
答案 2 :(得分:0)
这个怎么样?
class TrieNode():
def __init__(self, length = 32):
self.members = list()
self.length = length
for i in range(length):
self.members.append(None)
def set(self, idx, item):
if idx < self.length and idx >= 0:
self.members[idx] = item
else:
print "ERROR: Specified index out of range."
# Alternately, you could raise an IndexError.
def unset(self, idx):
if idx < self.length and idx >= 0:
self.members[idx] = None
else:
raise IndexError("Specified index out of range (0..%d)." % self.length)