8

トライ データ構造の作成に使用する Python オブジェクトの配列が必要です。タプルのように固定長で、リストのように変更可能な構造が必要です。リストが正確に正しいサイズであることを確認できるようにしたいので、リストを使用したくありません(余分な要素の割り当てを開始すると、トライが大きくなるにつれて、メモリのオーバーヘッドが急速に増加する可能性があります)。これを行う方法はありますか?オブジェクトの配列を作成してみました:

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

私がやろうとしていることを行うための最良の方法は何ですか?

4

3 に答える 3

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

Cythonobjectは自動的に再カウントされPyObject *ます。PyObject *小さなバガーを再カウントする責任を負う限り、いつでも独自の配列をロールすることができます。これは、重要なケースの大きな頭痛の種になる可能性があります。

于 2011-02-17T19:25:21.460 に答える
1

そのような構造体の固定サイズがほとんど必要ない場合は、サイズを格納するための 1 つのスロットを__slots__含む、統一された名前のクラスを作成することを検討します。sizeサイズ (スロット数) ごとに個別のクラスを宣言する必要があります。cdeclインデックスでスロットにアクセスする関数を定義します。アクセス パフォーマンスは、おそらく C 配列の単純なアドレス演算ほど大きくはありませんが、スロットの数が非常に多く、それ以上のスロットがないことは確かです。

于 2011-01-29T01:40:52.517 に答える
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)
于 2011-01-28T23:56:24.887 に答える