在大量嵌套的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)
如果我最终更新了它,我还创建了一个要点: