在初始化时填充defaultdict

wim*_*wim 4 python list-comprehension generator-expression defaultdict

我怎样才能获得一个可调用的工厂用于defaultdict以允许用理解填充它?我认为这可能不可能,但我想不出一个很好的理由呢?

>>> def foo(*args):
...     # TODO
...
>>> from collections import defaultdict
>>> thing = foo(defaultdict, int)
>>> d = thing((i, i*i) for i in range(3))
>>> d[2]
# should return 4
>>> d[-1]
# should return 0
Run Code Online (Sandbox Code Playgroud)

use*_*ica 7

defaultdict之后的任何参数default_factory都被视为参数dict:

>>> defaultdict(int, [(i, i*i) for i in range(5)])
defaultdict(<type 'int'>, {0: 0, 1: 1, 2: 4, 3: 9, 4: 16})
Run Code Online (Sandbox Code Playgroud)

只需通过理解defaultdict并让它完成工作:

def defaultdict_factory_factory(default_factory):
    def defaultdict_factory(*args, **kwargs):
        return defaultdict(default_factory, *args, **kwargs)
    return defaultdict_factory
Run Code Online (Sandbox Code Playgroud)

或使用functools.partial:

def defaultdict_factory_factory(default_factory):
    return partial(defaultdict, default_factory)
Run Code Online (Sandbox Code Playgroud)


Pet*_*son 5

你只是在找defaultdict.update

>>> from collections import defaultdict
>>> thing = defaultdict(int)
>>> thing.update((i, i*i) for i in range(3))
>>> thing
defaultdict(<type 'int'>, {0: 0, 1: 1, 2: 4})
Run Code Online (Sandbox Code Playgroud)

你可以将它放入一个函数中.

>>> def initdefaultdict(type_, *args, **kwargs):
...     d = defaultdict(type_)
...     d.update(*args, **kwargs)
...     return d
... 
>>> thing = initdefaultdict(int, ((i, i+10) for i in range(3)))
>>> thing
defaultdict(<type 'int'>, {0: 10, 1: 11, 2: 12})
>>> thing[3]
0
Run Code Online (Sandbox Code Playgroud)

或者为了满足您的原始要求,返回一个功能:

>>> def defaultdictinitfactory(type_): # this is your "foo"
...     def createupdate(*args, **kwargs):
...             d = defaultdict(type_)
...             d.update(*args, **kwargs)
...             return d
...     return createupdate
... 
>>> f = defaultdictinitfactory(int) # f is your "thing"
>>> d = f((i, i*i) for i in range(3))
>>> d
defaultdict(<type 'int'>, {0: 0, 1: 1, 2: 4})
>>> 
Run Code Online (Sandbox Code Playgroud)