【问题标题】:Access element of nested data structure created under function from function argument从函数参数的函数下创建的嵌套数据结构的访问元素
【发布时间】:2026-01-20 01:30:01
【问题描述】:

我有以下功能,我动态构建字典的字典(为了简单起见,这里 DoD 是静态创建的):

import json
def fun(dummyArg1, dummyArg2):
  DoD = {'a': {'aa':1, 'ab':2}, 'b': {'ba':3, 'bb':4}, 'c': '5'}
  print json.dumps(DoD, sort_keys=True, indent=4)
  # FURTHER CODE THAT WILL WORK WITH DoD VARIABLE GOES HERE

In [1]: fun(1,2)
Out[1]:
{
    "a": {
        "aa": 1,
        "ab": 2
    },
    "b": {
        "ba": 3,
        "bb": 4
    },
    "c": "5"
}

是否可以在函数调用期间指定特定的DoD 元素内容?我想要类似的东西:

fun(dummyArg1, dummyArg2, DoD["b"]["ba"] = "New Value")

我知道这是可能的,例如通过传递列表,其中第 0 个位置是新值,第一个位置是“外部”字典键,第二个位置是“内部”字典键:

import json
lst = ["New Value", "b", "ba"]
def fun(arg1, arg2, additionalParams):
  DoD = {'a': {'aa':1, 'ab':2}, 'b': {'ba':3, 'bb':4}, 'c': '5'}
  DoD[additionalParams[1]][additionalParams[2]] = additionalParams[0]
  print json.dumps(DoD, sort_keys=True, indent=4)
  # FURTHER CODE THAT WILL WORK WITH DoD VARIABLE GOES HERE

In [1]: fun(1,2,lst)
Out[1]:
{
    "a": {
        "aa": 1,
        "ab": 2
    },
    "b": {
        "ba": "New Value",
        "bb": 4
    },
    "c": "5"
}

但正如您所见,它不是很健壮(更改键 'c' 下的值需要重写函数代码)也不优雅。有更好的方法吗?

额外问题:为什么在分配 "ba" 后的最后一个示例中包含 ["New Value"] 而不是 "New Value"

PS:即使DoD 是动态创建的,也总会有DoD["b"]["ba"] 元素。

【问题讨论】:

  • 我可以回答你的额外问题 - 你设置 DOD['b']['ba'] = [ additionalParams[0] ]。 additionalParams[0] 是一个字符串,[additionalParams[0]] 是包含在列表中的相同字符串。关于您的其余问题,我不确定我是否理解您要做什么。您能否详细说明您希望您的功能做什么?它的输入是什么,期望的输出是什么?
  • @BHawk 谢谢,这是一个错字。所需的输入是这样的:fun(dummyArg1, dummyArg2, DoD["b"]["ba"] = "New Value") 你可以在最后一个代码 sn-p 上看到所需的输出。
  • 您可以将附加参数放入字符串中,然后执行 eval。在其他情况下,将执行分配... DoD 未在该范围内定义,因此会失败。将其添加到范围中对您定义整个 DoD 并将其作为参数传递没有太大帮助。

标签: python list dictionary arguments


【解决方案1】:

这是一种设置程序的奇怪方式,但假设您有自己的理由,我认为您可能正在寻找 splat 参数 [*args] 或 [**kwargs]。使用 splat 参数,您可以将“正式参数”又名“必需参数”传递给函数(在这种情况下为 dummyArg1,dummyArg2),然后是 splat arg。所以你的定义是

def fun(dummyArg1,dummyArg2,*args):

你的电话是

fun(1,2,'abc','def',4,'etc')

在您的代码中,args 将表示为一个元组 = ('abc','def',4,'etc')

然后你可以使用你的元组来整理你的字典遍历:

l = len(args)
if l == 3:
  DoD[args[1]][args[2]] = args[0]
elif l == 2:
  DoD[args[1]] = args[0]

当然,如果您的字典非常深,这可能会变得很麻烦,在这种情况下,您可能想查看更多 complex walking methods

【讨论】:

    【解决方案2】:

    您可以使用**kwargs 并检查root,即:

    import json
    
    def fun(arg1, arg2, root, **additionalParams):
      DoD = {'a': {'aa':1, 'ab':2}, 'b': {'ba':3, 'bb':4}, 'c': '5'}
    
      if root:
        DoD[root][additionalParams.keys()[0]] = additionalParams.values()[0]
      else:
        DoD[additionalParams.keys()[0]] = additionalParams.values()[0]
    
      print json.dumps(DoD, sort_keys=True, indent=4)
    

    测试1:

    fun(1,2, root="b", ba = "new value")
    

    输出:

    {
        "a": {
            "aa": 1, 
            "ab": 2
        }, 
        "b": {
            "ba": "new value", 
            "bb": 4
        }, 
        "c": "5"
    }
    

    测试2:

    fun(1,2, root=None, c = "new value")
    

    输出:

    {
        "a": {
            "aa": 1, 
            "ab": 2
        }, 
        "b": {
            "ba": 3, 
            "bb": 4
        }, 
        "c": "new value"
    }
    

    注意:您可以在 **additionalParams 中传递 root,但您应该考虑不保留传递给函数的关键字参数中的顺序。

    【讨论】: