【发布时间】:2015-02-02 04:26:46
【问题描述】:
我们正在尝试重构和修改 Python 程序,使其能够获取用户定义的 JSON 文件,解析该文件,然后根据用户想要并在 JSON 中定义的选项执行工作流.所以基本上,用户必须在 JSON 中指定一个字典,当这个 JSON 文件被 Python 程序解析时,我们获得一个 Python 字典,然后我们将它作为参数传递给我们在顶级模块中实例化的类.综上所述,用户定义的 JSON 字典最终会在 python 程序运行时添加到实例命名空间中。
实现上下文管理器来解析 JSON 输入对我们来说不是问题。但是,我们需要能够使用 JSON 字典(随后将其添加到实例命名空间中)和 generate multiple lines from a Jinja2 template file using looping within a template。我们尝试将此行用于 JSON 中的键值对之一:
"extra_scripts" : [["Altera/AlteraCommon.lua",
"Altera/StratixIV/EP4SGX70HF35C2.lua"]]
这是一个大字典对象,我们称它为option_space_dict,为了简单起见,它只有4个键值对(假设"extra_scripts"在这里是'key4'),尽管对于我们的程序,它要大得多:
option_space_dict = {
'key1' : ['value1'],
'key2' : ['value2'],
'key3' : ['value3A', 'value3B', 'value3C'],
'key4' : [['value4A', 'value4B']]
}
这是被这一行解析的:
import itertools
option_space = [ dict(itertools.izip(option_space_dict, opt)) for opt in itertools.product(*option_space_dict.itervalues()) ]
获取option_space,它与option_space_dict 的本质不同在于它类似于:
[
{ 'key1' : 'value1',
'key2' : 'value2',
'key3' : 'value3A'
'key4' : ['value4A', 'value4B'] },
{ 'key1' : 'value1',
'key2' : 'value2',
'key3' : 'value3B'
'key4' : ['value4A', 'value4B'] },
{ 'key1' : 'value1',
'key2' : 'value2',
'key3' : 'value3C'
'key4' : ['value4A', 'value4B'] }
]
所以我们生成的option_space 非常适合我们想要对 jinja2 模板执行的操作。然而,为了得到这个,我们添加到option_space_dict 的key4 键在程序的其他地方引起了问题:
# ignore self.option as it is not relevant to the issue here
def getOptionCompack(self) :
return [ (k, v) for k, v in self.option.iteritems() if set([v]) != set(self.option_space_dict[k])]
我收到错误 TypeError: unhashable type: 'list' 是因为 key4 的值包含一个嵌套列表结构,它是“不可散列的”。
所以我们遇到了障碍。有没有人对我们如何克服这个问题提出建议?能够以这种方式指定我们的 JSON 文件来执行我们对 Jinja2 的要求,同时仍然能够以相同的格式解析数据结构?
谢谢一百万!
【问题讨论】:
-
定义一种将列表转换为字符串并用于比较/散列的方法?例如,
''.join(sorted(my_list))?
标签: python json list dictionary jinja2