2012-02-20 2 views
5

私は、個々のファイルにデータを分割するためのオープンファイルの辞書を保持しようとしています。私が辞書からファイルを要求するとき、私はそれが鍵がそこになければ開かれたいと思います。しかし、デフォルトとしてラムダを使うことはできません。辞書のデフォルトとしてラムダを使用することは可能ですか?

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

fは結果ではなく関数に設定されているため、これは機能しません。上記の構文を使用してsetdefaultは動作しません。

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

答えて

7

このユースケースは、私はこのようなものは、PythonのSTDLIBに存在することを信じていない理由である、defaultdictはあまりにも複雑です:私はこの他にも何かできることはあります。ただし簡単にジェネリックを書くことができdefaultdictを「拡張」コールバックに欠けているの鍵を渡し、自分自身、:

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> 

これは、Python 2.7以降で動作し、知りません - 何か李

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 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 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

collectionsモジュールのdefaultdictを使用できます

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

それだけでこれはdict[key]構文はKeyErrorが提起正確な理由です

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

を行うには良いかもしれないけど。

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

のget()発生しません。項目が見つからない場合はキーエラーです。 []記法があります。例えばファイル[キー] – Jacob

関連する問題