2011-11-01 16 views
15

collections.defaultdict numaralı belgede kullanmak harika. Özellikle lambda ile bağlantılı olarak:Anahtar, collections.defaultdict

>>> import collections 
>>> a = collections.defaultdict(lambda : [None,None]) 
>>> a['foo'] 
[None, None] 

lambda verilen anahtar (örneğin 'foo') kullanmak için bir yolu var mı? Örneğin (çalışmıyor): istendiği gibi iyi çözüm (varsayılan çağrısı ile başlatmak gerekir ve daha sonra kullanmayın) muhtemelen olmasa

>>> a = collections.defaultdict(lambda : [None]*key) 
>>> a[1] 
[None] 
>>> a[2] 
[None, None] 
>>> a 
defaultdict(<function <lambda> at 0x02984170>, {1: [None], 2: [None, None]}) 

cevap

30

; vanilya __missing__ bir özel durum, ama sen bir alt sınıfta isterse onu yaparlar olabilir:

class A(dict): 
    def __missing__(self, key): 
     value = self[key] = [None] * key 
     return value 
+0

önce bu sihirli yöntemi hakkında bilmiyordum

d = KeyBasedDefaultDict(lambda key: [None] * key) d[1] > [None] d[2] > [None, None] 
, :), büyük: Söz açıklanan

Kullanımı olarak –

1

Bu, çalışacaktır. Diğer bazı yöntem (ler) i geçersiz kılarak muhtemelen düzeltilebilir.

class NoneDict(collections.defaultdict): 
    def __setitem__(self, key, value): 
     super(NoneDict, self).__setitem__(key, key*[None]) 
Muhtemelen dict bulunmayan bir öğeye erişmeyi denediğinizde dict üzerine denir __missing__ istiyorum
2

SingleNegationElimination ve rplnt ve the defaultdict documentation gelen cevapları birleştiren ben aşağıdaki çözümü kullanılır.

import collections 
class KeyBasedDefaultDict(collections.defaultdict): 
    def __missing__(self, key): 
     if self.default_factory is None: 
      raise KeyError(key) 
     self[key] = self.default_factory(key) 
     return self[key] 

yöntemin bedeni büyük ihtimalle sadece return self.default_factory(key) olabilir, ama ekstra kod tüm defaultdict davranışını çoğaltmak için emin olur.