在大量嵌套的defaultdict中计算事物的更具python风格的方法

在大量嵌套的defaultdict中计算事物的更具python风格的方法,python,defaultdict,Python,Defaultdict,我的代码当前必须将大量嵌套的dict中的内容计算到另一个中。我有需要由3个值索引的项目,然后计数。因此,在循环之前,我初始化嵌套的defaultdict,如下所示: from collections import defaultdict type_to_count_dic = defaultdict( lambda: defaultdict( lambda: defaultdict(int) ) ) 这使我能够在一个紧密的循环中

我的代码当前必须将大量嵌套的
dict
中的内容计算到另一个中。我有需要由3个值索引的项目,然后计数。因此,在循环之前,我初始化嵌套的
defaultdict
,如下所示:

from collections import defaultdict

type_to_count_dic = defaultdict(
        lambda: defaultdict(
            lambda: defaultdict(int)
        )
    )
这使我能够在一个紧密的循环中计算项目,如下所示:

for a in ...:
    for b in ...:
        for c in ...:
            type_to_count_dic[a][b][c] += 1

我觉得初始化所有那些
defaultdict
s就像在Java中声明类型一样。有没有一种更为惯用/通灵的方法来做这样的事情?

既然你在数东西,你应该用一个计数器来计算最里面的单词:

import collections
defaultdict = collections.defaultdict
Counter = collections.Counter

x = defaultdict(lambda: defaultdict(Counter))

for a in A:
    for b in B:
        x[a][b].update(C)
使用计数器可以访问有用的方法,例如

根据您打算如何使用此dict,您可能不需要进行深嵌套。相反,可以使用元组作为键。比如说,

import collections
import itertools as IT

A = range(2)
B = 'XYZ'
C = 'abc'
x = collections.Counter(IT.product(A, B, C))
print(x)
屈服

A = range(2)
B = 'XYZ'
C = 'abc'
x = collections.Counter(IT.product(A, B, C))
print(x)
Counter({(0, 'X', 'c'): 1, (0, 'Z', 'a'): 1, (1, 'Z', 'a'): 1, (1, 'X', 'c'): 1, (1, 'Z', 'b'): 1, (0, 'X', 'b'): 1, (0, 'Y', 'a'): 1, (1, 'Y', 'a'): 1, (0, 'Z', 'c'): 1, (1, 'Z', 'c'): 1, (0, 'X', 'a'): 1, (0, 'Y', 'b'): 1, (1, 'X', 'a'): 1, (1, 'Y', 'b'): 1, (0, 'Z', 'b'): 1, (1, 'Y', 'c'): 1, (1, 'X', 'b'): 1, (0, 'Y', 'c'): 1})
屈服

A = range(2)
B = 'XYZ'
C = 'abc'
x = collections.Counter(IT.product(A, B, C))
print(x)
Counter({(0, 'X', 'c'): 1, (0, 'Z', 'a'): 1, (1, 'Z', 'a'): 1, (1, 'X', 'c'): 1, (1, 'Z', 'b'): 1, (0, 'X', 'b'): 1, (0, 'Y', 'a'): 1, (1, 'Y', 'a'): 1, (0, 'Z', 'c'): 1, (1, 'Z', 'c'): 1, (0, 'X', 'a'): 1, (0, 'Y', 'b'): 1, (1, 'X', 'a'): 1, (1, 'Y', 'b'): 1, (0, 'Z', 'b'): 1, (1, 'Y', 'c'): 1, (1, 'X', 'b'): 1, (0, 'Y', 'c'): 1})

t=CountTree() >>>t['a'] defaultdict(,{}) >>>t['a']['b']['c']+=1 >>>打印t['a']['b']['c'] 1.
我假设您仅在满足某些条件时添加到每个计数器,或者可能根据条件添加不同的值?否则,每个计数器的值肯定总是1

这就是说,我能想到的最简单的解决方案是只创建一个dict,并在三个循环值的元组上键入。例如,类似这样的事情:

dict(((a,b,c),1) for a in A for b in B for c in C)

但正如我所说,这只会给你一个柜台。您需要将上面表达式中的1替换为一些条件或函数调用,这些条件或函数调用根据a、b和c的值返回更合适的值。

我也有类似的需要,并创建了以下内容:

import json

from collections import defaultdict


class NestedDefaultDict(defaultdict):
    def __init__(self, depth, default=int, _root=True):
        self.root = _root
        self.depth = depth
        if depth > 1:
            cur_default = lambda: NestedDefaultDict(depth - 1,
                                                    default,
                                                    False)
        else:
            cur_default = default
        defaultdict.__init__(self, cur_default)

    def __repr__(self):
        if self.root:
            return "NestedDefaultDict(%d): {%s}" % (self.depth,
                                                    defaultdict.__repr__(self))
        else:
            return defaultdict.__repr__(self)


# Quick Example
core_data_type = lambda: [0] * 10
test = NestedDefaultDict(3, core_data_type)
test['hello']['world']['example'][5] += 100
print test
print json.dumps(test)

# Code without custom class.
test = defaultdict(lambda: defaultdict(lambda: defaultdict(core_data_type)))
test['hello']['world']['example'][5] += 100
print test
print json.dumps(test)
如果我最终更新了它,我还创建了一个要点: