2012-06-19 13 views
11

मैं एक डेटा संरचना की तलाश में हूं जो दो अलग-अलग इंडेक्स के तहत समान मूल्य रखता है, जहां मैं या तो एक द्वारा डेटा तक पहुंच सकता हूं।एकाधिक अनुक्रमणिका के साथ एक शब्दकोश को लागू करने के लिए डेटा संरचना?

उदाहरण:

x = mysticalDataStructure() 
x.add(1,'karl', dog) 
x.add(2,'lisa', cat) 

$ x[1].age 
2 
$ x['karl'].age 
2 
$ x[1].age = 4 
$ x['karl'].age 
4 

क्या prerolled है, या क्या है सबसे अच्छा तरीका रोल करने मेरे अपने (मैं एक सूचकांक (संख्या 1 की वृद्धि के साथ एन 0 से जा रहा) के द्वारा उपलब्ध है, और के माध्यम से एक स्ट्रिंग)।

collections.ordereddict स्थिति के माध्यम से तेज़ यादृच्छिक पहुंच प्रतीत नहीं होता है, जहां तक ​​मुझे लगता है कि मैं इसे केवल तब तक चल सकता हूं जब तक कि मैं तत्व i तक पहुंच नहीं पाता (मैं सही क्रम में सम्मिलित कर सकता हूं)।

+0

आप एक कुंजी के माध्यम से एक मूल्य बदलते हैं तो आप उम्मीद करते हैं अन्य कुंजी के साथ पुनः प्राप्त करने के लिए नया मूल्य? – martineau

+0

@martineau: हाँ बिल्कुल – ted

+0

इस उत्तर/मॉड्यूल देखें: http://stackoverflow.com/questions/11449232/multiple-keys-per-value/16966988#16966988 – formiaczek

उत्तर

7
class MultiKeyDict(object): 

    def __init__(self, **kwargs): 
     self._keys = {} 
     self._data = {} 
     for k, v in kwargs.iteritems(): 
      self[k] = v 

    def __getitem__(self, key): 
     try: 
      return self._data[key] 
     except KeyError: 
      return self._data[self._keys[key]] 

    def __setitem__(self, key, val): 
     try: 
      self._data[self._keys[key]] = val 
     except KeyError: 
      if isinstance(key, tuple): 
       if not key: 
        raise ValueError(u'Empty tuple cannot be used as a key') 
       key, other_keys = key[0], key[1:] 
      else: 
       other_keys = [] 
      self._data[key] = val 
      for k in other_keys: 
       self._keys[k] = key 

    def add_keys(self, to_key, new_keys): 
     if to_key not in self._data: 
      to_key = self._keys[to_key] 
     for key in new_keys: 
      self._keys[key] = to_key 


    @classmethod 
    def from_dict(cls, dic): 
     result = cls() 
     for key, val in dic.items(): 
      result[key] = val 
     return result 

उपयोग:

>>> d = MultiKeyDict(a=1, b=2) 
>>> d['c', 'd'] = 3 # two keys for one value 
>>> print d['c'], d['d'] 
3 3 
>>> d['c'] = 4 
>>> print d['d'] 
4 
>>> d.add_keys('d', ('e',)) 
>>> d['e'] 
4 
>>> d2 = MultiKeyDict.from_dict({ ('a', 'b'): 1 }) 
>>> d2['a'] = 2 
>>> d2['b'] 
2 
+1

शायद एक '__delitem __()' होना चाहिए। – martineau

+0

@ मार्टिनौ, यह केवल – astynax

+0

अवधारणा को समझाने के लिए स्केच है, यह शुद्ध है, जबकि मुझे दो सूची एक्सेस करने की आवश्यकता है, मैं अपरिवर्तनीय प्रकार के उदाहरण भी स्टोर कर सकता हूं। – ted

1

बस तीन नक्शे का उपयोग करें।

maps = [dict(), dict(), dict()] 

def insert(rec): 
    maps[0][rec[0]] = rec 
    maps[1][rec[1]] = rec 
    maps[2][rec[2]] = rec 

रिक ऑब्जेक्ट के प्रमुख विशेषताओं में परिवर्तन के लिए पुन: सम्मिलन की आवश्यकता होगी। किसी अन्य मानचित्र की तरह, जब आप किसी ऑब्जेक्ट की कुंजी बदलते हैं।

नक्शे बस कुंजी के नक्शे -> वस्तु, सब के बाद। वे वास्तव में वस्तु की प्रतियों को संग्रहित नहीं करते हैं (यह केवल कचरा नहीं है)। तो एक नक्शा एक सूचकांक है, और कुछ नहीं। यदि आप तीन इंडेक्स चाहते हैं, तो तीन मानचित्रों का उपयोग करें। उन्हें प्रबंधित करने के लिए कुछ गोंद कोड फ़ंक्शन लिखें।

index = dict() 

def insert(rec): 
    index[rec[0]] = rec 
    index[rec[1]] = rec 
    index[rec[2]] = rec 

तो आप या तो यह तक पहुंच सकते हैं:

ट्रेवर से उल्लेख किया है, तो आप भी एक साझा शब्दकोश का उपयोग कर सकते हैं।

हालांकि कुंजी टकराव से सावधान!

+0

+1 मेरी बुरी तरह से तैयार उदाहरण के उत्तर देता है, लेकिन आप उदाहरण के लिए भूल गए हैं कि मेरे पास इंडेक्स भी हैं जो ऑब्जेक्ट से नहीं आते हैं, उदाहरण के लिए 'कुत्ते' – ted

11

वहाँ एक विशेष कारण है कि आप सिर्फ एक शब्दकोश का उपयोग नहीं कर सकता है:

x = {} 
x[1] = x['karl'] = dog 
x[2] = x['lisa'] = cat 

तो फिर तुम यह या तो द्वारा पहुँच सकते हैं।

तुम सच में अपने आप को दोहराने के लिए नहीं करना चाहते हैं आप ऐसा करते हैं:

class MysticalDataStructure(dict): 
    def add(self, key1, key2, value): 
     return self[key1] = self[key2] = value 

x = MysticalDataStructure() 
x.add(1, 'karl', dog) 
x.add(2, 'lisa', cat) 
+0

के लिए आईडी की तरह '1' यह साझा सूचकांक का उपयोग करके भी अच्छा है। –

+0

एक्स [1] को संशोधित नहीं करेगा x ['karl'] को संशोधित नहीं करेगा? –

+0

@ हंस निश्चित रूप से इसे संशोधित किया जाएगा, यह वही वस्तु है - वस्तुएं पाइथन में संदर्भ के रूप में पारित की जाती हैं (ऑब्जेक्ट संदर्भ के मूल्य से - http: // stackoverflow देखें।कॉम/ए/9 86145/1176601) – Aprillion

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