Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Cython中创建一个固定长度、可变的Python对象数组?_Python_Arrays_Cython_Trie_Python C Extension - Fatal编程技术网

如何在Cython中创建一个固定长度、可变的Python对象数组?

如何在Cython中创建一个固定长度、可变的Python对象数组?,python,arrays,cython,trie,python-c-extension,Python,Arrays,Cython,Trie,Python C Extension,我需要一个python对象数组,用于创建trie数据结构。我需要一个像元组一样长度固定,像列表一样可变的结构。我不想使用列表,因为我希望能够确保列表的大小完全正确(如果它开始分配额外的元素,随着trie的增大,内存开销可能会迅速增加)。有办法做到这一点吗?我尝试创建一个对象数组: cdef class TrieNode: cdef object members[32] …但这是一个错误: Error compiling Cython file: --------------------

我需要一个python对象数组,用于创建trie数据结构。我需要一个像元组一样长度固定,像列表一样可变的结构。我不想使用列表,因为我希望能够确保列表的大小完全正确(如果它开始分配额外的元素,随着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
做我想做的事情最好的方法是什么?

这个怎么样

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)
class三节点():
定义初始化(self,长度=32):
self.members=list()
self.length=长度
对于范围内的i(长度):
self.members.append(无)
def设置(自身、idx、项目):
如果idx=0:
self.members[idx]=项
其他:
打印“错误:指定的索引超出范围。”
#或者,您可以提出一个索引器。
def未设置(自身,idx):
如果idx=0:
self.members[idx]=无
其他:
提升索引器(“指定的索引超出范围(0..%d)。%self.length)

如果您只需要这种结构的几个固定大小,我会考虑使用统一命名的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuu
来创建类,包括一个
大小
插槽来存储大小。您需要为每个大小(插槽数量)声明一个单独的类。定义
cdecl
函数以按索引访问插槽。访问性能可能不会像使用C数组的纯地址算法那样好,但您可以确定,只有这么多插槽,没有更多插槽

我不知道最好的解决方案,但这里有一个解决方案:

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
来自cpython.ref cimport PyObject,Py_XINCREF,Py_XDECREF
DEF大小=32
cdef三级管:
cdef PyObject*成员[大小]
定义(自我):
cdef对象临时对象
对于范围内的i(尺寸):
临时对象=int(i)
#增加其refcount,使其不是gc'd。
#我们持有对该对象的引用,并负责
#在uuu dealoc uuuuuuuu中减少它。
Py_XINCREF(临时对象)
self.members[i]=临时对象
定义初始化(自):
#只是为了证明它是有效的。。。
对于范围内的i(尺寸):
打印self.members[i]
def uu dealoc uu(自我):
#确保我们减少了成员元素的引用。
对于范围内的i(尺寸):
Py_XDECREF(self.members[i])
self.members[i]=NULL

Cython
对象
是一个自动参照计数的
PyObject*
。只要你负责重新计算这些小错误,你就可以滚动你自己的
PyObject*
数组。对于非平凡的案例来说,这可能是一个非常令人头痛的问题。

我的首选是
assert 0对不起,但这与我所要寻找的根本不符。两件事:1)我正在寻找一种在cython中实现这一点的方法,以创建一个C扩展。2) 我没有办法强迫列表只包含32个元素。它的
len
为32,但通常会分配更多的空间以使附加更容易。