问题描述
special_dict = {}
# ...
if username not in special_dict:
special_dict[username] = {}
for subkey in ["Subkey1","Subkey2","Subkey3"]:
special_dict[username][subkey] = [] # or {},etc,depending on usecase
基本上我想要一个字典,其中对于每个用户名,值是另一个包含三个特定子键的字典,然后这些值是列表或集合或你有什么。
我对 defaultdict 很熟悉,但我不知道如何使这里的“值类型”变得非常具体。通常,如果我希望每个值都是默认列表,我通常会执行 defaultdict(list)
,但是有没有办法使默认值不是列表而是本身是特定类型的字典?
理想情况下,最后我想做的是 special_dict[username][subkey].append(item)
并且不必先担心用户名是否存在,因为如果不存在,它将成为一个键并且形成三个子键。
解决方法
您需要一个函数来创建您想要的结构,并将此函数作为参数传递给 defaultdict
:
from collections import defaultdict
def name_subdict():
return {'key1':[],'key2':set(),'key3':{}}
mydict = defaultdict(name_subdict)
mydict['John']['key1'].append(1)
mydict['John']['key2'].add(2)
mydict['Jane']['key3'][10] = 20
print(mydict)
# defaultdict(<function name_subdict at 0x7fcaf81193a0>,# {'John': {'key1': [1],'key2': {2},'key3': {}},# 'Jane': {'key1': [],'key2': set(),'key3': {10: 20}}})
回答您的评论:是的,您可以传递要用于所有子项的数据类型,如mydict = name_subdict(list)
。只有一个警告:defaultdict 的参数必须是一个不带参数的函数(或任何可调用的)。
因此,name_subdict(list)
应该返回一个函数来创建结构。
代码将是:
from collections import defaultdict
def name_subdict(data_type):
# data type must be a callable like list,set,dict...
def subdict_creator():
return {key:data_type() for key in ['key1','key2','key3']}
return subdict_creator
my_list_dict = defaultdict(name_subdict(list))
my_set_dict = defaultdict(name_subdict(set))
my_list_dict['John']['key1'].append(1)
my_list_dict['John']['key2'].append(2)
my_set_dict['Jane']['key3'].add(10)
print(my_list_dict)
# defaultdict(<function name_subdict.<locals>.subdict_creator at 0x7fcadbf27b80>,'key2': [2],'key3': []}})
print(my_set_dict)
# defaultdict(<function name_subdict.<locals>.subdict_creator at 0x7fcadbbf25e0>,# {'Jane': {'key1': set(),'key3': {10}}})