假设我的字典是
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 的不同解决方案持开放态度。
你可以尝试:
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}}]]}}}