2012-02-20 27 views
5

Verileri tek tek dosyalara ayırmak için açık dosyaların sözlüğünü tutmaya çalışıyorum. Sözlükden bir dosya istediğimde anahtarın orada olmaması durumunda açılmasını istiyorum. Ancak, lambda'yı varsayılan olarak kullanabiliyorum gibi görünmüyor.Bir lambda sözlük varsayılan olarak kullanmak mümkün mü?

örn.

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

Bu, işe yaramaz çünkü f işlevi sonuçtan ziyade işleve ayarlanır. Yukarıdaki sözdizimini kullanan setdefault da çalışmıyor.

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

cevap

7

Bu kullanım şekli Böyle bir şey Python stdlib bulunduğunu inanmıyorum bu yüzden, bir defaultdict için çok karmaşık: Bunu yanında yapabileceğim bir şey var mı.

from collections import defaultdict 

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

Kullanımı:

Bu Python 2.7+ çalışır
>>> files = BetterDefaultDict(lambda key: open(key, 'w')) 
>>> files['/tmp/test.py'] 
<open file '/tmp/test.py', mode 'w' at 0x7ff552ad6db0> 

, bilmem Bununla birlikte kolayca jenerik geri arama için eksik anahtarını geçtiği, defaultdict kendini "genişletilmiş" yazabilirsiniz - şey li

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

bir sınıf nesnesinin __getitem__() oldukça kolay olsun-ve-açık sarabilirdiniz: Ayrıca, yine bu dosyaları kapatmak unutmayın :) eski sürümleri 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

ihtiyacınız yapmalı bir alt sınıf için başka bir seçenek: -:

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
belki daha genel,

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] 

Ya değerler veya çağrılabilir ifadelerdir varsayılan izin

Varsayılanları koleksiyon modülünden

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

sadece bu dict[key] sözdizimi KeyError yükseltir nedenini tam nedenidir

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

yapacak daha iyi olabilir rağmen:

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

haline gelmelidir:

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

olsun() zam yok Öğe bulunamazsa bir anahtar hatası. [] notasyon yapar. Örneğin. dosya [anahtar] – Jacob

İlgili konular