python - Defaultdict 自动为每个键创建一个子字典?
问题描述
我有一本字典,我经常在我的代码中做这样的事情:
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>,
# {'John': {'key1': [1], 'key2': [2], 'key3': []}})
print(my_set_dict)
# defaultdict(<function name_subdict.<locals>.subdict_creator at 0x7fcadbbf25e0>,
# {'Jane': {'key1': set(), 'key2': set(), 'key3': {10}}})
推荐阅读
- reactjs - 尝试使用从 CDN 提供的包时,Typescript 抛出错误“未定义名称”
- python - 如何将 ROS msg 从一个 python 发布到另一个
- node.js - ElasticSearch-js { body } 未定义
- python-3.x - 按键时停止鼠标事件
- css - 如何在材质 ui makeStyles 中使用 @supports css 规则?
- java - 我在比较两个作为字符串的对象元素时遇到问题
- android - Android 模拟器在 Ubuntu 20.04 上非常慢
- c# - 错误请求被中止:无法创建 SSL/TLS 安全通道。仅在 Windows Server 2012 上
- java - Android Studio 在 ubuntu 系统上因 jre 致命错误而崩溃
- r - Dagitty 中的 LateX 名称