Python存储字典路径并读回

2024-06-17 12:25:11 发布

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

我在一个嵌套的列表字典(系统信息)上循环,并以以下格式存储到键的完整路径:

.children[0].children[9].children[0].children[0].handle = PCI:0000:01:00.0
.children[0].children[9].children[0].children[0].description = Non-Volatile memory controller
.children[0].children[9].children[0].children[0].product = Samsung Electronics Co Ltd
.children[0].children[9].product = Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2
.children[2].product = PWS-406P-1R

接下来,读取完整的路径,并将其与系统信息(数据)进行比较。如何将完整路径转换为这种格式?你知道吗

Data['children'][0]['children'][9]['children'][0]['children'][0]['handle']
Data['children'][0]['children'][9]['product]'
Data['children'][2]['product']

我可以这样做:

data = re.findall(r"\.([a-z]+)\[(\d+)\]", key, re.IGNORECASE)

[('children', '0'), ('children', '9'), ('children', '0'), ('children', '0')]
[('children', '0'), ('children', '9'), ('children', '0'), ('children', '0')]
[('children', '0'), ('children', '9'), ('children', '0'), ('children', '0')]
[('children', '0'), ('children', '9')]
[('children', '2')]

如何将这些元组列表之一转换为:

if Data['children'][2]['product'] == expected:
    print('pass')

Tags: 路径re信息列表data字典系统格式
3条回答

可以使用itertoolsfunctoolsoperator库将索引链接在一起,并递归地查找它们以获得最终值。你知道吗

首先,我认为应该更改regex以获取最后一个getter(即handle, description, product

re.findall(r"\.([a-z]+)(?:\[(\d+)\])?", key, re.IGNORECASE)

应该给你这个

[('children', '0'), ('children', '9'), ('product', '')]

然后你可以这样做来连锁查找

import operator
import functools
import itertools

indexes = [('children', '0'), ('children', '9'), ('product', '')]

# This turns the list above into a flat list ['children', 0, 'children', ...]
# It also converts number strings to integers and excludes empty strings.
keys = (int(k) if k.isdigit() else k for k in itertools.chain(*indexes) if k)

# functools.reduce recursively looks up the keys
# operator.getitem() is a functional version of Data[key] == getitem(Data, key)
value = functools.reduce(operator.getitem, keys, Data)
if value == expected:
    pass

它可以与Data结构中的递归搜索一起工作:

s = """.children[0].children[9].children[0].children[0].handle = PCI:0000:01:00.0
.children[0].children[9].children[0].children[0].description = Non-Volatile memory controller
.children[0].children[9].children[0].children[0].product = Samsung Electronics Co Ltd
.children[0].children[9].product = Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2
.children[2].product = PWS-406P-1R
"""

import re

Data = {'children': {'0': {'children': {'9': {'children': {'0': {'children': {'0': {'handle': 'value'}}}}}}}}}

for line in s.splitlines():
    l, value = re.split(r'\s*=\s*', line)
    l = l[1:] # Remove first '.'
    keys = re.split(r'[\[\].]+', l)
    print(keys)

    lookup = Data
    for key in keys:
        if key in lookup:
            lookup = lookup[key]
        else:
            print("Key {} not found".format(key))
            raise Exception("Value not found for {}".format(".".join(keys)))

    print("Value found: " + value)

第一次分割将键与数据分开(寻找=

l = l[1:]删除第一个“.”

第二个拆分将所有字段分隔为一个键列表,以访问数据。你知道吗

然后,在数据结构中有一个查找循环。你知道吗

我现在能想到的最简单的是:

代码:

s = '.children[2].product = PWS-406P-1R'
path, expected = re.sub(r'\.(\w+)', r"['\1']", s).split(' = ')
Data = {'children': ['', '', {'product': 'PWS-406P-1R'}]}

if eval(f'Data{path}') == expected:
    print('pass')

输出:

pass

注意^{}的用法需要python3.6+。如果你愿意,你可以把它改成^{}。你知道吗

相关问题 更多 >