2011-10-19 8 views
10

में सूचकांक कमजोर आदेशित सेट सेट मैं सोच रहा था कि पाइथन में एक सूचकांक कमजोर आदेशित सेट बनाने का कोई आसान तरीका है या नहीं। मैंने खुद को बनाने की कोशिश की। यहां मैं ये आया हूं:पायथन

""" 
An indexable, ordered set of objects, which are held by weak reference. 
""" 
from nose.tools import * 
import blist 
import weakref 


class WeakOrderedSet(blist.weaksortedset): 
    """ 
    A blist.weaksortedset whose key is the insertion order. 
    """ 
    def __init__(self, iterable=()): 
     self.insertion_order = weakref.WeakKeyDictionary() # value_type to int 
     self.last_key = 0 
     super().__init__(key=self.insertion_order.__getitem__) 
     for item in iterable: 
      self.add(item) 

    def __delitem__(self, index): 
     values = super().__getitem__(index) 
     super().__delitem__(index) 
     if not isinstance(index, slice): 
      # values is just one element 
      values = [values] 
     for value in values: 
      if value not in self: 
       del self.insertion_order[value] 

    def add(self, value): 
     # Choose a key so that value is on the end. 
     if value not in self.insertion_order: 
      key = self.last_key 
      self.last_key += 1 
      self.insertion_order[value] = key 
     super().add(value) 

    def discard(self, value): 
     super().discard(value) 
     if value not in self: 
      del self.insertion_order[value] 

    def remove(self, value): 
     super().remove(value) 
     if value not in self: 
      del self.insertion_order[value] 

    def pop(self, *args, **kwargs): 
     value = super().pop(*args, **kwargs) 
     if value not in self: 
      del self.insertion_order[value] 

    def clear(self): 
     super().clear() 
     self.insertion_order.clear() 

    def update(self, *args): 
     for arg in args: 
      for item in arg: 
       self.add(item) 


if __name__ == '__main__': 
    class Dummy: 
     def __init__(self, value): 
      self.value = value 

    x = [Dummy(i) for i in range(10)] 
    w = WeakOrderedSet(reversed(x)) 
    del w[2:8] 
    assert_equals([9,8,1,0], [i.value for i in w]) 
    del w[0] 
    assert_equals([8,1,0], [i.value for i in w]) 
    del x 
    assert_equals([], [i.value for i in w]) 

क्या ऐसा करने का कोई आसान तरीका है?

उत्तर

24

मानक पुस्तकालय में मौजूदा घटकों का लाभ उठाने का सबसे आसान तरीका है।

ऑर्डर्ड डिक्ट और म्यूटेबलसेट एबीसी ऑर्डर्डसेट लिखना आसान बनाता है।

इसी तरह, आप मौजूदा weakref.WeakSet पुन: उपयोग और एक OrderedSet साथ उसके अंतर्निहित सेट() की जगह ले सकता: हमेशा की तरह,

import collections, weakref 

class OrderedSet(collections.MutableSet): 
    def __init__(self, values=()): 
     self._od = collections.OrderedDict().fromkeys(values) 
    def __len__(self): 
     return len(self._od) 
    def __iter__(self): 
     return iter(self._od) 
    def __contains__(self, value): 
     return value in self._od 
    def add(self, value): 
     self._od[value] = None 
    def discard(self, value): 
     self._od.pop(value, None) 

class OrderedWeakrefSet(weakref.WeakSet): 
    def __init__(self, values=()): 
     super(OrderedWeakrefSet, self).__init__() 
     self.data = OrderedSet() 
     for elem in values: 
      self.add(elem) 
+1

बहुत अच्छा! 'Weakref.WeakSet' के 'डेटा' सदस्य कहां से दस्तावेज है? –

+4

वीकसेट के लिए दस्तावेज़ अपूर्ण हैं (लगभग मौजूद नहीं हैं)। –

+1

पायपी वही (या बहुत समान) 'वीकसेट' कार्यान्वयन का उपयोग करता है, इसलिए यह वहां भी काम करता है ('gc.collect()' को कमजोरियों को हटाने के लिए आवश्यक है)। – simonzack

1

रेमंड एक महान और संक्षिप्त जवाब है, लेकिन मैं वास्तव में यहाँ थोड़ी देर के लिए आया था सूचकांक भाग में रुचि रखते हैं, कमजोर हिस्से से अधिक। मैंने अंततः अपना जवाब बनाया, जो the IndexedSet type in the boltons utility library बन गया। असल में, यह list और set एपीआई के संयुक्त सभी बेहतरीन भागों हैं।

>>> x = IndexedSet(list(range(4)) + list(range(8))) 
>>> x 
IndexedSet([0, 1, 2, 3, 4, 5, 6, 7]) 
>>> x - set(range(2)) 
IndexedSet([2, 3, 4, 5, 6, 7]) 
>>> x[-1] 
7 
>>> fcr = IndexedSet('freecreditreport.com') 
>>> ''.join(fcr[:fcr.index('.')]) 
'frecditpo' 

तो weakref हिस्सा महत्वपूर्ण आप की संभावना विरासत या कोड की एक प्रति के प्रत्यक्ष संशोधन के माध्यम से इसे जोड़ सकते हैं (मॉड्यूल स्टैंडअलोन शुद्ध अजगर, और 2/3 संगत है)।