【问题标题】:Python: defaultdict(dict) how to create nested dictionary?Python:defaultdict(dict) 如何创建嵌套字典?
【发布时间】:2016-10-06 10:56:24
【问题描述】:

我需要从目录中的所有文件中获取字符串并以某种方式记录它们,因此我尝试使用 defaultdict 来创建它,但我很难弄清楚如何逐步添加到字典的每一层。本质上,字典应该是这样的:

文件名

捆绑

信息

捆绑

信息

文件名

捆绑

信息

等 我将信息作为一个列表,所以我可以将我需要的任何内容附加到列表中,但是当我在这里运行我所拥有的内容时,我最终会为每个文件名获得一个包和信息。似乎 update() 函数正在替换里面的值,我不确定如何让它继续添加,然后为每个 Bundle 创建一个更新的字典。感谢您提供任何帮助,如有任何混淆,我们深表歉意。


import collections
import os

devices = collections.defaultdict(lambda: collections.defaultdict(dict))
# bundles = collections.defaultdict(dict)

for filename in os.listdir('.'):
    if os.path.isfile(filename):
        if '.net' in filename:
            dev = open(filename)

            for line in dev:

                line = line.strip()
                values = line.split(' ')

                if values[0] == 'interface':
                    bundle_name = values[1]
                    if '/' in bundle_name:
                        pass
                    else:
                        if len(values) == 2:
                            ur_device = devices[filename]
                            ur_device.update(
                                {
                                    'bundle_name': bundle_name,
                                    'bundle_info': [],
                                }
                            )

                if 'secondary' in values:
                    pass
                elif values[0] == 'ipv4' and values[1] == 'address' and len(values) == 4:
                    ur_device['bundle_info'].append(
                        {
                            'ip_address': values[2],
                            'subnet_mask': values[3],
                        }
                    )

            dev.close()

【问题讨论】:

    标签: python dictionary nested defaultdict


    【解决方案1】:

    字典是有一个键和一个值的东西,任何时候你把一些东西放到一个有相同键的字典中,它就会替换那个值。例如:

    dictionary = {}
    # Insert value1 at index key1
    dictionary["key1"] = "value1"
    
    # Overwrite the value at index key1 to value2
    dictionary["key1"] = "value2"
    
    print(dictionary["key1"]) # prints value2
    

    您的代码有一些没有意义的东西,但我建议您使用上述语法来实际将内容添加到字典中(而不是用于添加键列表的更新方法/值对到字典中)。

    下面我用#**'s标记了一些对你的代码的建议

    import collections
    import os
    
    #** I'm guessing you want to put your devices into this dict, but you never put anything into it
    devices = collections.defaultdict(lambda: collections.defaultdict(dict))
    # bundles = collections.defaultdict(dict)
    
    for filename in os.listdir('.'):
        if os.path.isfile(filename):
            if '.net' in filename:
                dev = open(filename)
    
                for line in dev:
    
                    line = line.strip()
                    values = line.split(' ')
                    #** declare bundle_name out here, it is better form since we will make use of it in the immediate scopes below this
                    bundle_name = ''
    
                    if values[0] == 'interface':
                        bundle_name = values[1]
                        if '/' in bundle_name:
                            pass
                        else:
                            if len(values) == 2:
                                #** This is assuming you populated devices somewhere else??
                                devices[filename][bundle_name] = []
    
                    if 'secondary' in values:
                        pass
                    elif values[0] == 'ipv4' and values[1] == 'address' and len(values) == 4:
                        #** ur_device was not declared in this scope, it is a bad idea to use it here, instead index it out of the devices dict
                        #** it also might be worth having a check here to ensure devices[filename] actually exists first
                        devices[filename][bundle_name].append(
                            {
                                'ip_address': values[2],
                                'subnet_mask': values[3],
                            }
                        )
    
                dev.close()
    

    ** 编辑 **

    查看您的问题,您需要为每个文件名提供多个捆绑包。但是您的字典结构不够详细,并且您似乎没有提供有关如何使用数据初始化设备的代码。

    基本上,您应该考虑字典的每个级别将具有哪些键,而不仅仅是什么值。

    设备(文件名:设备)
    device (bundle_name?: info) info(您将详细信息附加到的列表)

    我根据您的意图更改了上面的代码。

    【讨论】:

    • 感谢您的洞察力!我最终让它工作了,你的 cmets 帮助我简化了它。
    猜你喜欢
    • 1970-01-01
    • 2018-11-28
    • 1970-01-01
    • 1970-01-01
    • 2023-01-18
    • 2020-09-26
    • 2021-04-04
    • 2017-12-27
    • 1970-01-01
    相关资源
    最近更新 更多