gpt4 book ai didi

用于处理嵌套字典的 Python 递归 setattr() 类函数

转载 作者:太空狗 更新时间:2023-10-29 21:03:35 26 4
gpt4 key购买 nike

<分区>

有很多不错的类似getattr()的函数用于解析嵌套的字典结构,例如:

我想做一个并行的 setattr()。本质上,给定:

cmd = 'f[0].a'
val = 'whatever'
x = {"a":"stuff"}

我想生成一个可以分配的函数:

x['f'][0]['a'] = val

或多或少,这将以与以下相同的方式工作:

setattr(x,'f[0].a',val)

产生:

>>> x
{"a":"stuff","f":[{"a":"whatever"}]}

我目前称它为 setByDot():

setByDot(x,'f[0].a',val)

这样做的一个问题是,如果中间的键不存在,则需要检查并创建一个中间键(如果它不存在)---即,对于上述内容:

>>> x = {"a":"stuff"}
>>> x['f'][0]['a'] = val
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'f'

因此,您首先必须:

>>> x['f']=[{}]
>>> x
{'a': 'stuff', 'f': [{}]}
>>> x['f'][0]['a']=val
>>> x
{'a': 'stuff', 'f': [{'a': 'whatever'}]}

另一个是下一项是列表时的键控与下一项是字符串时的键控不同,即:

>>> x = {"a":"stuff"}
>>> x['f']=['']
>>> x['f'][0]['a']=val
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

...失败,因为赋值是针对空字符串而不是空字典。空字典将是字典中每个非列表的正确赋值,直到最后一个——它可能是一个列表或一个值。

@TokenMacGuy 在下面的评论中指出的第二个问题是,当您必须创建一个不存在的列表时,您可能必须创建大量空白值。所以,

setattr(x,'f[10].a',val)

---可能意味着算法将不得不做一个像这样的中间体:

>>> x['f']=[{},{},{},{},{},{},{},{},{},{},{}]
>>> x['f'][10]['a']=val

屈服

>>> x 
{"a":"stuff","f":[{},{},{},{},{},{},{},{},{},{},{"a":"whatever"}]}

这就是与 getter 关联的 setter...

>>> getByDot(x,"f[10].a")
"whatever"

更重要的是,中间体应该/不/覆盖已经存在的值。

以下是我迄今为止的一个垃圾想法——我可以识别列表与字典和其他数据类型,并在它们不存在的地方创建它们。但是,我看不到 (a) 将递归调用放在哪里,或者 (b) 当我遍历列表时如何“构建”深层对象,以及 (c) 如何区分/probing/我正在就像我从/setting/构造深层对象一样,当我到达堆栈的末尾时我必须做。

def setByDot(obj,ref,newval):
ref = ref.replace("[",".[")
cmd = ref.split('.')
numkeys = len(cmd)
count = 0
for c in cmd:
count = count+1
while count < numkeys:
if c.find("["):
idstart = c.find("[")
numend = c.find("]")
try:
deep = obj[int(idstart+1:numend-1)]
except:
obj[int(idstart+1:numend-1)] = []
deep = obj[int(idstart+1:numend-1)]
else:
try:
deep = obj[c]
except:
if obj[c] isinstance(dict):
obj[c] = {}
else:
obj[c] = ''
deep = obj[c]
setByDot(deep,c,newval)

这看起来非常棘手,因为如果你正在制作占位符,你必须向前看以检查/next/对象的类型,并且你必须向后看以在你前进时建立一条路径.

更新

我最近有 this question也回答了,这可能是相关的或有帮助的。

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com