【问题标题】:Trying to grow a nested dictionary by adding more key:value pairs尝试通过添加更多键值对来增加嵌套字典
【发布时间】:2015-01-06 11:58:31
【问题描述】:

尝试将更多键:值对添加到本身嵌套在另一个字典对象中的字典对象时,我遇到了一些麻烦。此外,使用dict[key] = value 为字典分配额外的键:值对的常用方法在这里不适合我的情况(我将在后面解释原因),因此这使我的目标更具挑战性。

我将通过我的源代码中的一些语句来说明我想要实现的目标。

首先,我有一个包含嵌套的字典对象:

environment = { 'v' : 
                  {
                   'SDC_PERIOD':'{period}s'.format(period = self.period),
                   'FAMILY':'{legup_family}s'.format(legup_family = self.legup_family),
                   'DEVICE_FAMILY':'"{fpga_family}s"'.format(fpga_family = self.fpga_family)
                   }
              }

然后按照这一行,我将进行if 测试,如果通过,将要求我添加另一个字典:

environment_add = { 'v' : {'LM_LICENSE_FILE' : '1800@adsc-linux'} , 
                    'l' : 'quartus_full' }

最终形成这本完整的字典:

environment = { 'v' : 
                  {
                   'SDC_PERIOD':'{period}s'.format(period = self.period),
                   'FAMILY':'{legup_family}s'.format(legup_family = self.legup_family),
                   'DEVICE_FAMILY':'"{fpga_family}s"'.format(fpga_family = self.fpga_family),
                   'LM_LICENSE_FILE' : '1800@adsc-linux'
                   } ,
                'l' : 'quartus_full'
              }

如您所见,如果我尝试使用 dict[key] = value 语法分配一个新的键:值对,它对我不起作用,因为它最终会为我创建一个新的键:值对,或覆盖现有的字典对象和嵌套在'v' 键下的键值对。

到目前为止,为了完成字典的创建,我一直在使用以下:

environment = """{ v: {'SDC_PERIOD':'%(period)s','FAMILY':'%(legup_family)s','DEVICE_FAMILY':'"%(fpga_family)s"'}}""" % self
if self.require_license:  # this is the if statement test that I was referring to earlier
  environment = environment.replace('}', '')
  environment += """ ,'LM_LICENSE_FILE':'1800@adsc-linux'}, 'l': 'quartus_full'}"""

然后通过以下方式获取字典对象:

import ast
env_dict = ast.literal_eval(environment)

有效地将environment 字符串转换为存储在新变量名env_dict 下的字典对象。

我的队友认为这太过分了,特别是因为 environmentenv_dict 对象稍后将在 2 个单独的模块中解析。在第一个模块中,键值对将被分解和重构以形成看起来像 '-v SDC_PERIOD=2500s, LM_LICENSE_FILE=1800@adsc-linux' 的字符串,而在第二个模块中,字典嵌套在 'v' 键下(环境/env_dict 字典对象)将被提取出来并直接作为参数提供给接受映射对象的函数。

如您所见,完成这项工作需要相当多的精确解析,虽然我的方法实现了目标,但我的团队不接受它,他们认为必须有更好的方法来做这直接来自 environment 是字典对象而不是字符串对象。

非常感谢您学习我的详细帖子,如果您有任何帮助或建议,我将不胜感激!

【问题讨论】:

    标签: python string dictionary replace abstract-syntax-tree


    【解决方案1】:
    for k,v in environment_add.iteritems(): # .items() in Python 3
        if k in environment:
            environment[k].update(v)
        else:
            environment[k] = v
    

    也就是说,对于每个要添加的项目,检查它是否存在,如果存在则更新它,或者直接创建它。这假定要添加的项目(如果存在)将是 dicts(您不能更新像 quartus_full 这样的字符串)。

    【讨论】:

    • 感谢您的建议!我对python还是很陌生,所以对于您提供的代码,我仍然有些不太了解,但否则我明白您的意思。我知道for 循环的作用,但我还没有看到很多具有多个目标的for 循环,语法如下:for target in object。因此,在您的情况下,k 目标是否映射到 environment_add 的“键”,而 v 目标是否映射到 environment_add 的“值”(恰好是嵌套字典)?
    • 也可以说“这假定要添加的项目,如果它们存在,将是 dicts(你不能更新像 quartus_full 这样的字符串)。”你的意思是对于我在environment_add 字典中的'l':'quartus_full' 对,我将无法对其进行任何更改,例如在'l' 键中创建一个新的嵌套字典,甚至更改将'quarts_full' 值换成别的东西?
    • @AKKO:是的,k,v 语法只是一个 tupleiteritems() 产生一个 2 元组序列(即对)。至于 quartus_full 的东西,试试看。 :)
    • 更新:.iteritems() 在 python 3.6+ 中不起作用,但 .items() 可以
    【解决方案2】:

    为什么不直接使用更新

    In [4]: dict_ = {"a": {"b": 2, "c": 3}}
    
    In [5]: dict_["a"].update(d=4)
    
    In [6]: dict_
    Out[6]: {'a': {'b': 2, 'c': 3, 'd': 4}}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-14
      • 1970-01-01
      • 2020-08-17
      • 2018-08-17
      • 1970-01-01
      • 2019-12-17
      相关资源
      最近更新 更多