从分隔的字符串创建多级字典(未知深度)

2024-04-23 17:36:58 发布

您现在位置:Python中文网/ 问答频道 /正文

对于一个“heath check”项目,我试图从文本文件中写入的字符串创建一个多维数组。你知道吗

目前,我使用的是这样的单变量:

someParameter1 = someValue1 # With some comments
someParameter2 = someValue2 # With some other comments

这将被翻译成字典:

ini['someParameter1'] = 'someValue1'
ini['someParameter2'] = 'someValue2'

现在我只是在表上添加了检查,因此我使用二维数组,由破折号分隔的字符串构建,如下所示:

someTable-someParameter1 = someValue1 # With some comments
someTable-someParameter2 = someValue2 # With some other comments

这将被翻译成两级词典:

ini['someTable']['someParameter1'] = 'someValue1'
ini['someTable']['someParameter2'] = 'someValue2'

为此,我硬编码了“=”符号前2个字段的限制:

# In case the key contains a dash, create a 2-dimensional key
for inikey in list(ini):  # loop thru the ini to find key's with a dash
    if '-' in inikey:
        part1,part2 = inikey.split('-',1)    # <= Only split on the first dash
        try:
            ini[part1][part2] = ini[inikey]
        except KeyError:  # In case ini[part1] does not exist yet
            ini[part1] = {}
            ini[part1][part2] = ini[inikey]

因此,当我的配置文件中有:aaa-bbb-ccc-ddd = xyz时,它将被转换为ini['aaa']['bbb-ccc-ddd'] = 'xyz'

现在我寻找一个好的技巧来创建ini['aaa']['bbb]['ccc']['ddd'] = 'xyz',而不必为每个预期的级别编写一段代码。 因此,如果可能的话,在=,前面加上3,4,或任何数量的单词,创建一个维度未知的列表,尽可能深。你知道吗


Tags: thekeywithsomecommentsinipart2part1
2条回答

您可以使用^{}并使用默认dict创建它。如果您将其称为Tree,则我们有一个递归数据结构:

from collections import defaultdict

def Tree():
    return defaultdict(Tree)

这将在每次使用新密钥时创建新的子树:

>>> tree = Tree()
>>> tree['a']['b']['c'] = 123

如果我们有一个密钥列表,我们可以循环遍历它们,跟踪每个子树,直到我们使用了除最后一个密钥以外的所有密钥。然后我们为最后一个子树中的最后一个键设置值:

ini = Tree()

config_line = 'aaa-bbb-ccc-ddd = xyz'
keys, value = config_line.split(' = ')

keys = keys.split('-')

subtree = ini
for key in keys[:-1]:
    subtree = subtree[key]

subtree[keys[-1]] = value

您可以按破折号将键拆分为父键和最终键,然后在缺少父键的情况下遍历父键以生成子目录,最后为每行输入将当前值指定给当前节点的最终键:

from io import StringIO

file = StringIO('''someParameter1 = someValue1
someParameter2 = someValue2
someTable-someParameter1 = someValue1
someTable-someParameter2 = someValue2
aaa-bbb-ccc-ddd = xyz''')

ini = {}
for line in file:
    node = ini
    key, value = line.rstrip().split(' = ')
    *parents, key = key.split('-')
    for parent in parents:
        node[parent] = node = node.get(parent, {})
    node[key] = value

ini将变成:

{'someParameter1': 'someValue1',
 'someParameter2': 'someValue2',
 'someTable': {'someParameter1': 'someValue1', 'someParameter2': 'someValue2'},
 'aaa': {'bbb': {'ccc': {'ddd': 'xyz'}}}}

演示:https://repl.it/@blhsing/ForkedSufficientNumericalanalysis

相关问题 更多 >