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

标签 python iterator generator

假设我的字典是

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

我想编写如下代码:

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

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

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

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

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

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 的不同解决方案持开放态度。

最佳答案

你可以尝试:

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}}]]}}}

关于用于嵌套字典键的 Python 生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76931480/

相关文章:

javascript - 我们可以用 ES6 Generator 做哪些不能用 for 循环做的事情?

java - 两个字符生成随机序列

android - 通过移动数据发送 POST 请求

python - 在两个 numpy 形状对象数组上应用成对形状函数

python - hasattr 调用了哪种魔法方法?

C++0x 元组没有迭代器,对吗?

java - 修改迭代中的前一项

python - izip 的示例代码如何工作?

python - 根据子字符串拆分和排序列表

java - 可逆迭代器