使用infinite_defaultdict的价格

nev*_*int 5 python recursion dictionary

这对我来说是天堂派来的:

>>> from collections import defaultdict
>>> infinite_defaultdict = lambda: defaultdict(infinite_defaultdict)
>>> d = infinite_defaultdict() 
>>> d['x']['y']['z'] = 10
Run Code Online (Sandbox Code Playgroud)

作者:Raymond Hettinger在Twitter上

有了这个我不明白为什么我们应该这样做:

mydict = defaultdict(list)
mydict = defaultdict(lambda: defaultdict(float))
Run Code Online (Sandbox Code Playgroud)

等等....

但我可能错了.有没有你想避免的情况infinite_defaultdict

更新: 我试图对时间进行基准测试

from collections import defaultdict

def infdd():
   infinite_defaultdict = lambda: defaultdict(infinite_defaultdict)
   idd = infinite_defaultdict()
   idd['x'] = [1,2,3]

def plaindd():
   ddl  = defaultdict(list)
   ddl['x'] = [1,2,3]

if __name__ == '__main__':
    import timeit
    print "Infd = %.3f" % (timeit.timeit("infdd()",setup="from __main__ import infdd"))
    print "Plaind = %.3f" % (timeit.timeit("plaindd()",setup="from __main__ import plaindd"))
Run Code Online (Sandbox Code Playgroud)

显然,infinite_dict几乎是正常速度的两倍:

Infd = 0.632
Paind = 0.387
Run Code Online (Sandbox Code Playgroud)

dpe*_*rcy 1

如果您需要默认值不是字典,那么您不应该使用infinite_defaultdict. 例如,如果您想要对项目进行计数或累积项目数组,则您将希望默认值是数字或数组。

def group_by(key, items):
    result = defaultdict(list)
    for item in items:
        result[key(item)].append(item)
    return result

group_by(len, ['here', 'are', 'some', 'words'])
# -> { 3: ['are'] 4: ['here', 'some'], 5: ['words'] }
Run Code Online (Sandbox Code Playgroud)