用于嵌套字典键的 Python 生成器

问题描述 投票:0回答:1

假设我的字典是

data = {'a': {'b': {'c': {'d': 1}}}}

我想编写类似的代码:

for k,v in iterator(data):
    if some_conditions(k,v):
        v = some_value()

对于字典的所有键,我想检查键、值对是否匹配某些条件,并在必要时更新字典中的值。这个想法是我不必跟踪密钥链来设置新值。

那么,为什么不用迭代器呢?

这个想法似乎不错,我会循环遍历字典的所有键,并在满足条件时动态更新值。但我在实现这个时遇到了一些麻烦,原因可能是我缺乏迭代器的经验。

我尝试编写一些代码,但失败了,我不明白为什么:

def gen(dic):
    for k,v in dic.items():
        if isinstance(v, dict):
            yield v
            gen(v)

g = gen(data)
next(g)

最终数据更复杂:某些值可能是以字典作为成员的列表,我还必须处理这些字典。

data = {'a': {'b': {'c': [{'d': 1, 'e': 2}, 1, {'g': 1, 'h': 2}, [{'i': {'j': 1}}]]}}}

但是如果我能用一个简单的字典算出来,我就可以为更大的情况编写代码。我对不使用迭代器但保持干净和 Pythonic 的不同解决方案持开放态度。

python iterator generator
1个回答
0
投票

你可以尝试:

class Value:
    def __init__(self, v):
        self.v = v


def iterator(o):
    if isinstance(o, dict):
        for k, v in o.items():
            yield k, (val := Value(v))
            o[k] = val.v
            yield from iterator(v)
    if isinstance(o, list):
        for v in o:
            yield from iterator(v)


# return True if key is `d` and v is `1`
def some_condition(k, v):
    return k == "d" and v == 1


data = {"a": {"b": {"c": {"d": 1}}}}

for k, val in iterator(data):
    if some_condition(k, val.v):
        val.v = 10

print(data)

打印:

{'a': {'b': {'c': {'d': 10}}}}

使用更复杂的输入:

data = {"a": {"b": {"c": [{"d": 1, "e": 2}, 1, {"g": 1, "h": 2}, [{"i": {"j": 1}}]]}}}


def some_condition(k, v):
    return k == "h" and v == 2


for k, val in iterator(data):
    if some_condition(k, val.v):
        val.v = 9999

print(data)

打印(请注意

h
键的值已更改):

{"a": {"b": {"c": [{"d": 1, "e": 2}, 1, {"g": 1, "h": 9999}, [{"i": {"j": 1}}]]}}}
© www.soinside.com 2019 - 2024. All rights reserved.