如何使用特定的数据结构作为 defaultdict 的 default_factory?
How to use a specific data structure as the default_factory for a defaultdict?
我目前正在使用 Counter
的 defaultdict
来唯一地计算不可预测键的几个不可预测值:
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})})
我现在需要扩展 defaultdict
中值的结构并使其成为具有两个键的 dict
:前一个 Counter
和一个 str
:
mystruct = {
'counter': collections.Counter(),
'name': ''
}
是否可以使用特定的数据结构(如上)作为defaultdict
中的default_factory
?预期结果是,对于 defaultdict
中每个不存在的键,将创建一个使用上述结构初始化的新键和值。
您只需将 default_factory 定义为一个函数,returns 您想要默认的字典:
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)
drootang 答案的替代解决方案是使用自定义 class:
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})})
我目前正在使用 Counter
的 defaultdict
来唯一地计算不可预测键的几个不可预测值:
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})})
我现在需要扩展 defaultdict
中值的结构并使其成为具有两个键的 dict
:前一个 Counter
和一个 str
:
mystruct = {
'counter': collections.Counter(),
'name': ''
}
是否可以使用特定的数据结构(如上)作为defaultdict
中的default_factory
?预期结果是,对于 defaultdict
中每个不存在的键,将创建一个使用上述结构初始化的新键和值。
您只需将 default_factory 定义为一个函数,returns 您想要默认的字典:
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)
drootang 答案的替代解决方案是使用自定义 class:
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})})