python - 动态构建 Python 字典不会返回所需的结果
问题描述
我正在尝试ResourcesBuilder
在 Python 3.7 中编写一个类:
- 需要一些 JSON 数据:
accounts
: 字典和父子账户列表service
: 一些字符串标识符data
: 可以是字典、列表或字符串
- 使用输入数据动态构建嵌套字典并将其作为 JSON 返回
import json
class ResourcesBuilder:
def __init__(self):
self.parent_account = {}
self.accounts = {}
def build(self, parent_account, child_account, service, data):
self.parent_account[child_account] = {service: data}
self.accounts[parent_account] = self.parent_account
def main():
accounts = json.loads('{"p_acc_1": ["c_acc_1a", "c_acc_1b"], "p_acc_2": ["c_acc_2a", "c_acc_2b"]}')
service = 'test_service'
builder = ResourcesBuilder()
for parent_account in accounts:
for a_account in accounts[parent_account]:
data = 'test_data'
builder.build(parent_account, a_account, service, data)
print(json.dumps(builder.accounts, indent=4, sort_keys=True))
if __name__ == "__main__":
main()
运行时,上面的代码当前返回:
## CURRENT OUTCOME
{
"p_acc_1": {
"c_acc_1a": {
"test_service": "test_data"
},
"c_acc_1b": {
"test_service": "test_data"
},
"c_acc_2a": {
"test_service": "test_data" <--- this should not be returned
},
"c_acc_2b": {
"test_service": "test_data" <--- this should not be returned
}
},
"p_acc_2": {
"c_acc_1a": {
"test_service": "test_data" <--- this should not be returned
},
"c_acc_1b": {
"test_service": "test_data" <--- this should not be returned
},
"c_acc_2a": {
"test_service": "test_data"
},
"c_acc_2b": {
"test_service": "test_data"
}
}
}
如您所见,它列出了所有父帐户下的所有子帐户,而不是仅在其各自帐户下列出子帐户:
# DESIRED OUTCOME
{
"p_acc_1": {
"c_acc_1a": {
"test_service": "test_data"
},
"c_acc_1b": {
"test_service": "test_data"
}
},
"p_acc_2": {
"c_acc_2a": {
"test_service": "test_data"
},
"c_acc_2b": {
"test_service": "test_data"
}
}
}
我从 python 开始,所以我真的很感激我如何更好地实现我的目标。
解决方案
基本上,在您的功能的第二步中,您build
实际上是将您创建的整个字典链接回帐户。您只需复制您为其分配的父级的子级词典self.accounts[parent_account]
。由于在for
子列表的循环中,您无法一次显式获取所有子数据,因此您需要创建一个新函数来链接父字典。
import json
class ResourcesBuilder:
def __init__(self):
self.parent_account = {}
self.accounts = {}
def build(self, parent_account, child_account, service, data):
self.parent_account[child_account] = {service: data}
# This function links the parent correctly
# i.e., link only those dictionaries which are children of the
# current parent
def link_parent(self, parent_account, child_list):
self.accounts[parent_account] = {k: self.parent_account[k]
for k in child_list}
def main():
accounts = json.loads('{"p_acc_1": ["c_acc_1a", "c_acc_1b"], "p_acc_2": ["c_acc_2a", "c_acc_2b"]}')
service = 'test_service'
builder = ResourcesBuilder()
for parent_account in accounts:
for a_account in accounts[parent_account]:
data = 'test_data'
builder.build(parent_account, a_account, service, data)
# Now once the children nodes have been created, link the parent
builder.link_parent(parent_account, accounts[parent_account])
print(json.dumps(builder.accounts, indent=4, sort_keys=True))
if __name__ == "__main__":
main()
您可以参考这个带有工作代码的Google Colab 笔记本以获取更多信息。
推荐阅读
- c# - 使用 VSCode 在调试会话中间移动断点
- php - 带有翻译和碳的 Laravel 数据表 - 第一行默认语言问题
- git - 当我的本地不是最新的时,如何从远程拉取?
- vue.js - 如何卸载 vue-cli 2.xx
- internationalization - 免费在线服务从不同国家发送短信
- xaml - 如何在 xaml 中居中网格列标题?
- csv - 如何从 JMeter 中的 CSV 文件替换 GET 路径变量?
- reactjs - 如何将图像从 JSON 文件放到 React Native Js 页面
- gcc - 错误:'::acos' 尚未使用 ::acos 声明;
- sql-server - VM 上的 Azure SQL Server 可以作为生产数据库吗?