2011-01-28 11 views
7

मुझे ट्राई डेटास्ट्रक्चर बनाने में उपयोग करने के लिए पाइथन ऑब्जेक्ट्स की एक सरणी की आवश्यकता है। मुझे एक ऐसी संरचना की ज़रूरत है जो एक लूपल और एक सूची की तरह परिवर्तनीय की तरह निश्चित लंबाई होगी। मैं एक सूची का उपयोग नहीं करना चाहता क्योंकि मैं यह सुनिश्चित करने में सक्षम होना चाहता हूं कि सूची बिल्कुल सही आकार (यदि यह अतिरिक्त तत्वों को आवंटित करना शुरू कर देती है, तो स्मृति ओवरहेड बहुत तेज़ी से बढ़ सकता है क्योंकि ट्राई बड़ा हो जाता है)। क्या इसे करने का कोई तरीका है? मैं वस्तुओं की एक सरणी बनाने की कोशिश की:मैं साइथन में पाइथन ऑब्जेक्ट्स की एक निश्चित-लंबाई, परिवर्तनीय सरणी कैसे बना सकता हूं?

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

इस बारे में कैसे?

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) 
+0

मेरी वरीयता 'assert 0 <= idx

+1

क्षमा करें, लेकिन यह जो भी मैं ढूंढ रहा हूं उसके दाहिने ballpark में भी नहीं है। दो चीजें: 1) मैं सी एक्सटेंशन बनाने के लिए साइथन में ऐसा करने का एक तरीका ढूंढ रहा था। 2) मेरे पास सूची में 32 तत्वों को लेने के लिए मजबूर करने का कोई तरीका नहीं है। इसमें 32 का 'लेन' है, लेकिन आमतौर पर अधिक जगह जोड़ने के लिए आवंटित किया जाता है। –

1

आप केवल इस तरह की संरचना की कुछ तय आकार की जरूरत है, मैं समान रूप से __slots__ नामित साथ कक्षाएं बनाने, आकार स्टोर करने के लिए एक size स्लॉट सहित देखो चाहते हैं। आपको प्रत्येक आकार (स्लॉट की संख्या) के लिए एक अलग वर्ग घोषित करने की आवश्यकता होगी। सूचकांक द्वारा स्लॉट तक पहुंचने के लिए cdecl फ़ंक्शन को परिभाषित करें। एक्सेस प्रदर्शन शायद सी सी सरणी के सादे पते अंकगणित के साथ उतना ही बड़ा नहीं होगा, लेकिन आप सुनिश्चित होंगे कि केवल इतना स्लॉट हैं और कोई भी नहीं।

4

मैं सबसे अच्छा समाधान के बारे में पता नहीं है, लेकिन यहाँ एक समाधान है:

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 * refcounted है। जब तक आप छोटे buggers को refcounting के लिए जिम्मेदारी लेते हैं, तब तक आप PyObject * के अपने स्वयं के सरणी हमेशा रोल कर सकते हैं। यह गैर-मामूली मामलों के लिए एक प्रमुख सिरदर्द हो सकता है।

संबंधित मुद्दे