2012-02-20 12 views
5

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

उदा।

files = {} 
for row in data: 
    f = files.get(row.field1, lambda: open(row.field1, 'w')) 
    f.write('stuff...') 

यह काम नहीं करता है क्योंकि एफ इसके परिणाम के बजाय फ़ंक्शन पर सेट है। उपरोक्त वाक्यविन्यास का उपयोग करके setdefault या तो काम नहीं करता है।

f = files.get(row.field1) 
if not f: 
    f = files[row.field1] = open(row.field1, 'w') 

उत्तर

7

यह उपयोग के मामले में defaultdict के लिए बहुत जटिल है, जिसके कारण मैं नहीं मानता कि कुछ इस तरह अजगर stdlib में मौजूद है: क्या मैं इस के अलावा कुछ कर सकते हैं।

from collections import defaultdict 

class BetterDefaultDict(defaultdict): 
    def __missing__(self, key): 
    return self.setdefault(key, self.default_factory(key)) 

उपयोग::

>>> files = BetterDefaultDict(lambda key: open(key, 'w')) 
>>> files['/tmp/test.py'] 
<open file '/tmp/test.py', mode 'w' at 0x7ff552ad6db0> 

यह अजगर 2.7+ में काम करता है, के बारे में पता नहीं है तुम तथापि आसानी से एक सामान्य "बढ़ाया" defaultdict खुद के, जो कॉलबैक करने के लिए लापता कुंजी गुजरता लिख ​​सकते हैं पुराने संस्करणों :) इसके अलावा, भूल नहीं है उन फ़ाइलों को फिर से बंद करने के लिए:

finally: 
    for f in files.values(): f.close() 
2

आप एक वर्ग वस्तु की __getitem__() बहुत आसानी से में मिलता है और खुला लपेट सकता है - कुछ ली ke:

class FileCache(object): 
    def __init__(self): 
     self.map = {} 

    def __getitem__(self,key): 
     if key not in self.map:    
      self.map[key] = open(key,'w') 
     return self.map.key 
1

एक उपवर्ग के लिए एक और विकल्प है कि तुम क्या जरूरत है क्या करना चाहिए: -:

class CallableDefaultDict(dict): 

    def get(self, key, default=None): 
     try: 
      return self[key] 
     except KeyError: 
      return default() if callable(default) else default 

    def setdefault(self, key, default=None): 
     if not self.has_key(key): 
      self[key] = default() if callable(default) else default 
     return self[key] 
1

class LambdaDefaultDict(dict): 

    def get(self, key, default=None): 
     try: 
      return self[key] 
     except KeyError: 
      return default() 

    def setdefault(self, key, default=None): 
     if not self.has_key(key): 
      self[key] = default() if default else None 
     return self[key] 

या, शायद अधिक सामान्य चूक है कि मूल्यों या प्रतिदेय अभिव्यक्ति कर रहे हैं अनुमति देने के लिए

आप संग्रह मॉड्यूल से डिफ़ॉल्ट डिक्शन का उपयोग कर सकते हैं

class FileCache(collections.defaultdict): 
    def __missing__(self, key): 
    fo = open(key, 'w') 
    self[key] = fo 
    return fo 

हालांकि यह बेहतर हो सकता है बस क्या करना

files = {} 
def get_file(f): 
    fo = files.get(f) 
    if fo is None: 
    fo = open(f, 'w') 
    files[f] = fo 
    return fo 

for row in data: 
    f = get_file(row.field1) 
    f.write('stuff...') 
1

यह सटीक कारण dict[key] वाक्य रचना को जन्म देती है KeyError है:

files = {} 
for row in data: 
    f = files.get(row.field1, lambda: open(row.field1, 'w')) 
    f.write('stuff...') 

हो जाना चाहिए:

files = {} 
for row in data: 
    try: f = files[row.field1] 
    except KeyError: f = open(row.field1, 'w') 
    f.write('stuff...') 
+1

प्राप्त() बढ़ा नहीं है आइटम नहीं मिला है तो एक महत्वपूर्ण त्रुटि। [] नोटेशन करता है। जैसे फ़ाइलें [कुंजी] – Jacob

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