6

我目前正在使用defaultdictofCounter来唯一地计算不可预测键的几个不可预测值:

from collections import defaultdict, Counter

d = defaultdict(Counter)
d['x']['b'] += 1
d['x']['c'] += 1
print(d)

这给了我预期的结果:

defaultdict(<class 'collections.Counter'>, {'x': Counter({'c': 1, 'b': 1})})

我现在需要扩展 the 中的值的结构,defaultdict并使用两个键使其成为 a dict:previousCounter和 an str

mystruct = {
    'counter': collections.Counter(),
    'name': ''
}

是否可以使用特定的数据结构(如上)作为default_factoryin defaultdict?预期的结果是,对于 中的每个不存在的键,defaultdict将创建一个使用上述结构初始化的新键和值。

4

2 回答 2

9

您只需要将您的 default_factory 定义为一个函数,该函数返回您想要默认为的字典:

from collections import defaultdict, Counter
d = defaultdict(lambda: {'counter': Counter(), 'name': ''})
d['x']['counter']['b'] += 1
d['x']['counter']['c'] += 1
print(d)

如果您不熟悉 lambda,这与以下内容相同:

def my_factory():
    aDict = {'counter': Counter(), 'name':''}
    return aDict
d = defaultdict(my_factory)
于 2015-07-30T12:31:19.273 回答
1

drootang答案的另一种解决方案是使用自定义类:

from collections import defaultdict, Counter

class NamedCounter:
    def __init__(self, name = '', counter = None):
        self.counter = counter if counter else Counter()
        self.name = name

    def __repr__(self):
        return 'NamedCounter(name={}, counter={})'.format(
                repr(self.name), repr(self.counter))

d = defaultdict(NamedCounter)
d['x'].counter['b'] += 1
d['x'].counter['b'] += 1
d['x'].name = 'X counter'
print(d)

defaultdict(<class __main__.NamedCounter at 0x19de808>, {'x': NamedCounter(name='X counter', counter=Counter({'b': 2}))})

或者,您可以扩展Counter以将名称合并到计数器本身中:

from collections import defaultdict, Counter

class NamedCounter(Counter):
    def __init__(self, name = '', dict = None):
        super(Counter, self).__init__(dict if dict else {})
        self.name = name

    def __repr__(self):
        return 'NamedCounter(name={}, dict={})'.format(
                repr(self.name), super(Counter, self).__repr__())

d = defaultdict(NamedCounter)
d['x']['b'] += 1
d['x']['b'] += 1
d['x'].name = 'X counter'
print(d)

defaultdict(<class '__main__.NamedCounter'>, {'x': NamedCounter(name='X counter', dict={'b': 2})})

于 2015-07-30T13:11:10.017 回答