2012-02-17 10 views
5

विषय पर यहाँ पर कई सवाल के रूप में प्रमाणित की उप-समूह की खुद dict दृश्य बनाने के ले जा रहा एक शब्दकोश का एक टुकड़ा एक बहुत आम कार्य है, एक काफी अच्छा समाधान के साथ:अजगर, शब्दकोश

{k:v for k,v in dict.viewitems() if some_test(k,v)} 

लेकिन जो अपने स्वयं के मैपिंग के साथ एक नया शब्दकोश बनाता है। कई परिचालनों के लिए, मूल ताना का अपरिवर्तनीय दृश्य होना अच्छा होगा (यानी यह दृश्य पर असाइनमेंट या हटाना संचालन का समर्थन नहीं करता है)। इस तरह के एक प्रकार को लागू करना शायद आसान है, लेकिन स्थानीय उपयोगिता वर्गों का प्रसार करना अच्छा नहीं है।

तो, मेरा प्रश्न है: क्या ऐसा "सबसेट व्यू" प्राप्त करने का एक अंतर्निहित तरीका है? या क्या कोई तीसरी पार्टी लाइब्रेरी है (अधिमानतः पीईपीआई के माध्यम से उपलब्ध है) जो ऐसी उपयोगिता का अच्छा कार्यान्वयन प्रदान करती है?

+1

मैं सुझाव दूंगा कि एक शब्दकोश पर एक "अपरिवर्तनीय दृश्य" बिल्कुल आपके उदाहरण कोड के साथ मिलता है ... क्योंकि अनुपस्थिति शब्दकोश की एक अलग प्रति बना रही है, मुझे यकीन नहीं है कि आप कैसे बना रहे हैं "अपरिवर्तनीय" भाग का काम। – larsks

+0

@larsks: यह असाइनमेंट का समर्थन नहीं कर सकता है। – Marcin

+1

@larsks: मुझे लगता है कि "अपरिवर्तनीय दृश्य" द्वारा ओपी का अर्थ है कि व्यू ऑब्जेक्ट के पास शब्दकोश को म्यूट करने के लिए कोई तरीका नहीं है (जैसे पॉप), और लिपटे निर्देश में कोई भी परिवर्तन तुरंत दृश्य में दिखाई देता है। बेशक, यह "गहरी" भावना में अपरिवर्तनीय नहीं है - यानी, यदि आप my_view [some_key] .append (12) करते हैं, तो निश्चित रूप से 12 के अनुरूप मान संशोधित किया जाएगा। –

उत्तर

4

यह लागू करने के लिए बहुत आसान है:

from collections import Mapping 
class FilteredItems(Mapping): 
    def __init__(self, source, filter): 
     self.source = source 
     self.p = filter 

    def __getitem__(self, key): 
     x = self.source[key] 
     if self.p(key,x): 
      return key,x 
     else: 
      raise KeyError(key) 


d2 = FilteredItems(d, some_test) 
+0

+1 हां, यह कार्यान्वित करने में बहुत आसान है, और यह अच्छा लगता है, लेकिन जैसा कि ध्यान दिया गया है, स्थानीय कार्यान्वयन और नाम बहुत सारे हैं। – theheadofabroom

+2

का उपयोग करने के लिए – Marcin

2

अर्थ विज्ञान स्पष्ट करने के लिए, आप कुछ इस तरह की सोच रहे हैं :?

class FilteredDictView: 
    def __init__(self, base_dict, test): 
     self._base_dict = base_dict 
     self._test = test 
    def __getitem__(self, key): 
     value = self._base_dict[key] # might throw KeyError 
     if not self._test(key,value): 
      throw KeyError(key) 
     return value 
    # ... implement remaining dict-like-methods ... 

यदि ऐसा है, तो मुझे ऐसी किसी तीसरे पक्ष की कक्षा के बारे में पता नहीं है। यदि आप शेष विधियों को थोड़ा आसान बनाना चाहते हैं, तो आप बेस क्लास के रूप में "UserDict" का उपयोग करने पर विचार कर सकते हैं, जो मूल रूप से केवल ताना के लिए एक रैपर है ("UserDict.data" विशेषता को लपेटा हुआ टूल स्टोर करने के लिए उपयोग किया जाता है) ।

+0

हाँ, बिल्कुल उस तरह की चीज। – Marcin

4

एक शब्दकोश में देखने के लिए कोई अंतर्निहित तरीका नहीं लगता है। सबसे आसान कामकाज जोचेन का दृष्टिकोण प्रतीत होता है। विभिन्न __repr__() विधि की वजह से मुद्रण के लिए छोड़कर सभी पहलुओं में

from collections import MutableMapping 

class DictView(MutableMapping): 
    def __init__(self, source, valid_keys): 
     self.source, self.valid_keys = source, valid_keys 

    def __getitem__(self, key): 
     if key in self.valid_keys: 
      return self.source[key] 
     else: 
      raise KeyError(key) 

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

    def __iter__(self): 
     for key in self.valid_keys: 
      yield key 

    def __setitem__(self, key, value): 
     if key in self.valid_keys: 
      self.source[key] = value 
     else: 
      raise KeyError(key) 

    def __delitem__(self, key): 
     self.valid_keys.remove(key) 

d = dict(a=1, b=2, c=3) 
valid_keys = ['a', 'c'] 
d2 = DictView(d, valid_keys) 
d2['a'] = -1 # overwrite element 'a' in source dictionary 
print d # prints {'a': -1, 'c': 3, 'b': 2} 

तो d2 बर्ताव करता है एक शब्दकोश की तरह,: मैं थोड़ा इसे अपने उद्देश्यों के लिए काम करने के लिए अपने कोड अनुकूलित। से __repr__() प्राप्त करने के लिए collections.OrderedDict के लिए किए गए अनुसार प्रत्येक विधि के पुनर्मूल्यांकन की आवश्यकता होगी। अगर कोई केवल एक पठनीय दृश्य चाहता है, तो कोई collections.Mapping से प्राप्त कर सकता है और __setitem__() और __delitem__() के कार्यान्वयन को बचा सकता है। मुझे DictViewself.__dict__ से पैरामीटर चुनने के लिए उपयोगी लगता है और उन्हें कॉम्पैक्ट फॉर्म में पास करता है।

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

  • कोई संबंधित समस्या नहीं^_^