动态构建Python字典不会返回所需的结果

我正在尝试在Python 3.7中编写一个类ResourcesBuilder

  • 获取一些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,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开始,所以我将非常感激如何更好地实现自己的目标。

感谢您抽出宝贵的时间对此进行研究!

谢谢你, 乔治·M。

dwbo00 回答:动态构建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,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,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()

您可以参考this Google Colab notebook和工作代码以获取更多信息。

,

您几乎有伙伴,只需在父循环的每次迭代中清除父帐户

import json


class ResourcesBuilder:
    def __init__(self):
        self.parent_account = {}
        self.accounts = {}

    def build(self,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",data)
        builder.parent_account = {}  ## Here I've made change
    print(json.dumps(builder.accounts,sort_keys=True))


if __name__ == "__main__":
    main()
,

两个答案(Narendra和Mohammed的答案)都是正确且有用的,如果可以作为答案,我会选择它们两者:)! 最后选择Narendra是因为它对我作为初学者来说更加明确。 穆罕默德(Mohammed),很抱歉,如果我最终没有基于我的无知选择您的答案。

更新:在仔细研究了穆罕默德的答案后,我决定更优雅地处理该问题,即使对于新手来说并不明显。

非常感谢!

本文链接:https://www.f2er.com/3139638.html

大家都在问