访问defaultdict工厂中的密钥

dan*_*ast 12 python dictionary python-2.7 defaultdict

我想尝试做类似的事情:

from   collections import defaultdict
import hashlib

def factory():
    key = 'aaa'
    return { 'key-md5' : hashlib.md5('%s' % (key)).hexdigest() }

a = defaultdict(factory)
print a['aaa']
Run Code Online (Sandbox Code Playgroud)

(实际上,我之所以需要访问工厂中的密钥,不是为了计算md5,而是出于其他原因;这只是一个例子)

正如你所看到的,在工厂里我无法访问密钥:我只是强迫它,这没有任何意义.

是否可以以defaultdict我可以在工厂中访问密钥的方式使用?

fal*_*tru 19

__missing__defaultdict不及格key到出厂功能.

如果default_factory不是None,则在没有参数的情况下调用它来为给定键提供默认值,将该值插入键的字典中并返回.

使用自定义__missing__方法创建自己的字典类.

>>> class MyDict(dict):
...     def __init__(self, factory):
...         self.factory = factory
...     def __missing__(self, key):
...         self[key] = self.factory(key)
...         return self[key]
... 
>>> d = MyDict(lambda x: -x)
>>> d[1]
-1
>>> d
{1: -1}
Run Code Online (Sandbox Code Playgroud)

  • @Alexey,因为有时静态值并不能解决问题,这是我的猜测。这比不传递丢失的密钥更糟糕,没有任何东西可以传递给它。此外,具有可变类型的静态值是完全不行的,每个丢失的键都将指向同一个对象。 (2认同)

Mer*_*ius 5

不幸的是,不是直接的,因为defaultdict指定必须在没有参数的情况下调用default_factory:

http://docs.python.org/2/library/collections.html#collections.defaultdict

但是可以使用defaultdict作为具有所需行为的基类:

class CustomDefaultdict(defaultdict):
    def __missing__(self, key):
        if self.default_factory:
            dict.__setitem__(self, key, self.default_factory(key))
            return self[key]
        else:
            defaultdict.__missing__(self, key)
Run Code Online (Sandbox Code Playgroud)

这对我有用:

>>> a = CustomDefaultdict(factory)
>>> a
defaultdict(<function factory at 0x7f0a70da11b8>, {})
>>> print a['aaa']
{'key-md5': '47bce5c74f589f4867dbd57e9ca9f808'}
>>> print a['bbb']
{'key-md5': '08f8e0260c64418510cefb2b06eee5cd'}
Run Code Online (Sandbox Code Playgroud)

  • 无需使用“defaultdict”作为基类:[自Python 2.2](https://docs.python.org/2/library/userdict.html)“dict”可以直接子类化。 (2认同)