2012-04-30 18 views
6

संभव डुप्लिकेट: क्योंकि यह अपनी वस्तुओं में से एक के बराबर हैक्या ओ (1) समय में किसी सेट से आइटम प्राप्त करने का कोई तरीका है?

>>> item1 = (1,) 
>>> item2 = (2,) 
>>> s = set([item1, item2]) 
>>> s 
set([(2,), (1,)]) 
>>> new_item = (1,) 
>>> new_item in s 
True 
>>> new_item == item1 
True 
>>> new_item is item1 
False 

तो new_items में है, लेकिन यह है:
Python: Retrieve items from a set

निम्नलिखित कोड पर विचार करें एक अलग वस्तु।

क्या मैं चाहता हूँ s से item1 प्राप्त करने के लिए दिए गए new_items में है।

एक समाधान मैं के साथ आए हैं सीधा लेकिन बहुत ही कुशल नहीं है:

def get_item(s, new_item): 
    for item in s: 
     if item == new_item: 
      return item 

>>> get_item(s, new_item) is new_item 
False 
>>> get_item(s, new_item) is item1 
True 

एक अन्य समाधान अधिक कुशल लगता है, लेकिन वास्तव में काम नहीं करता है:

def get_item_using_intersection1(s, new_item): 
    return set([new_item]).intersection(s).pop() 

न ही यह एक:

def get_item_using_intersection2(s, new_item): 
    return s.intersection(set([new_item])).pop() 

क्योंकि चौराहे एक अपरिभाषित तरीके से काम करता है:

>>> get_item_using_intersection1(s, new_item) is new_item 
True 
>>> get_item_using_intersection1(s, new_item) is item1 
False 

>>> get_item_using_intersection2(s, new_item) is new_item 
True 
>>> get_item_using_intersection2(s, new_item) is item1 
False 

यदि यह मायने रखता है, तो मैं विंडोज 7 पर पायथन 2.7 x64 का उपयोग कर रहा हूं, लेकिन मुझे एक क्रॉस-प्लेटफ़ॉर्म समाधान की आवश्यकता है।


सभी के लिए धन्यवाद।

class SearchableSet(set): 

    def find(self, item): 
     for e in self: 
      if e == item: 
       return e 

जो निम्नलिखित समाधान के साथ भविष्य में बदल दिया जाएगा (जो अभी बहुत अधूरा है): मैं निम्नलिखित अस्थायी समाधान के साथ आया था

class SearchableSet(object): 

    def __init__(self, iterable=None): 
     self.__data = {} 
     if iterable is not None: 
      for e in iterable: 
       self.__data[e] = e 

    def __iter__(self): 
     return iter(self.__data) 

    def __len__(self): 
     return len(self.__data) 

    def __sub__(self, other): 
     return SearchableSet(set(self).__sub__(set(other))) 

    def add(self, item): 
     if not item in self: 
      self.__data[item] = item 

    def find(self, item): 
     return self.__data.get(item) 
+1

लेकिन ... "अपर्याप्त समाधान" आप पहले से ही रैखिक हैं। – kennytm

+0

मुझे लगता है कि उसका मतलब है * स्थिर * समय –

+0

@ केनीटीएम, धन्यवाद, मैंने अपना प्रश्न शीर्षक संपादित किया है। – utapyngo

उत्तर

12

एक set का उपयोग न करें, तो । बस dict का उपयोग करें जो कुछ मूल्यों को स्वयं ही मानचित्र करता है। आपके मामले में, यह नक्शे:

d[item1] = item1 
d[item2] = item2 

तो कुछ भी है कि item1 के बराबर है d में पाया जाएगा, लेकिन मूल्य item1 ही है। और यह रैखिक समय से काफी बेहतर है ;-)

पीएस मुझे उम्मीद है कि मैं आपके प्रश्न के इरादे को सही ढंग से समझ गया हूं। यदि नहीं, तो कृपया इसे स्पष्ट करें।

+0

धन्यवाद। मुझे पता है कि 'dict 'का उपयोग करना संभव है लेकिन मुझे यह भी पता है कि तकनीकी रूप से' सेट 'के साथ रहना संभव है (माना जाता है कि एक आंतरिक विधि है जो हैश द्वारा एक वस्तु पा सकती है)। इसके अलावा, मैं अपने पुराने कोड को फिर से लिखना नहीं चाहता क्योंकि मैं सेट ऑपरेशंस का गहन रूप से उपयोग करता हूं। – utapyngo

+7

@utapyngo: यदि यह गलत है तो पुराने कोड को फिर से लिखना बेहतर है। 'सेट' बस इसके लिए डिज़ाइन नहीं किया गया है - एक अधिक उपयुक्त डेटा संरचना का उपयोग करें। –

+0

रैखिक समय में ऐसे डिक्ट्स में इनर्सक्शन, यूनियन और अंतर कैसे करें? – utapyngo

2

आप पूरी तरह हे की जरूरत है (1) देखने और वस्तु पहचान (न केवल समानता) और तेजी से सेट संचालन, काफी फिर एक (नए सेट हर बार जब आप सेट संचालन करना चाहते हैं बनाए बिना) सीधा दृष्टिकोण dict और set दोनों का उपयोग करना है। आपको उन्हें संरचनाओं में रखने के लिए दोनों संरचनाओं को बनाए रखना होगा, लेकिन इससे आपको ओ (1) पहुंच (केवल एक बड़े स्थिर कारक के साथ) रखने की अनुमति मिल जाएगी।(और हो सकता है कि आप अपने "भविष्य के समाधान के साथ आगे बढ़ रहे हैं जो आपके संपादन में अभी बहुत अधूरा है।)

हालांकि, आपने उस डेटा की मात्रा का उल्लेख नहीं किया है जिसके साथ आप काम कर रहे हैं, या क्या आपके पास होने वाली प्रदर्शन समस्याओं की तरह, यदि कोई हो। तो मुझे विश्वास नहीं है कि आपको वास्तव में ऐसा करने की ज़रूरत है। यह dict के साथ set निर्माण के साथ, या set रैखिक लुकअप के साथ हो सकता है, पहले से ही पर्याप्त तेज़ है।

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