我有使用JSON文件作为输入的代码 - JSON文件中的每个条目都是模拟运行的唯一配置。下面是JSON文件的一行(扩展)的简化示例。您可以拥有数千个这样的行,每个行都有不同的唯一值。
{
"1": {
"description": "unique configuration 1",
"attribute to change": 1750,
"object type 1": {
"object name": {
"number": 10,
"object attribute 1": 5
}
},
"object type 2": {
"object name": {
"number": 5,
"object attribute 1": 50
}
}
}
}
效果很好。但是,每当我希望对配置文件进行更改时,我需要手动执行此操作,如果您有数千个条目,则可能会很乏味。我希望能够加载默认的JSON结构(如上所述)并自动创建所需的变体。
我创建了以下代码,几乎就在那里。
def generate_config_file(input_data, attribute, new_value):
for key, value in input_data.items():
if isinstance(value, dict):
if attribute in value:
value[attribute] = new_value
else:
generate_config_file(value, attribute, new_value)
elif key == attribute:
input_data[attribute] = new_value
file_name = input('Enter file name: ')
if len(file_name) < 1:
file_name = 'default structure.JSON'
id_num = 1
out_file = open('new config file.JSON', "a")
# so here create a new file with multiple rows
# where "attribute to change" is the attribute modified
# here between 5 and 95 in steps of 5
for i in range(5, 100, 5):
with open(file_name) as data_file:
data = json.load(data_file)
# give the new row a unique id_num
data[str(id_num)] = data.pop('1')
generate_config_file(data[str(id_num)], 'attribute to change', i)
json.dump(data, out_file, sort_keys=True, indent=4)
id_num += 1
out_file.close()
我希望输出看起来如下(除了你有19行)。我已经折叠到顶层,但在每一行(1,2,3 .... 19)内,结构应与上面的默认值相匹配。行之间的唯一区别是与要更改的属性关联的值。
{
"1": {},
"2": {},
"3": {}
}
然而它产生:
{
"1": {}
}{
"2": {}
}{
"3": {}
}
我尝试过各种各样的事情。例如将输出转换为字符串并尝试去除额外的{}并替换为'。我还尝试了在转储每个输出部分时删除外部{}并替换。既不工作,我现在不确定该尝试什么。
任何帮助表示赞赏。
答案 0 :(得分:1)
你正在做的是将json数据转储到for循环中,它总是会转储一个字典,它总会产生你现在获得的数据,以解决这个问题。我建议你创建一个像这样的新词典(new_data),
new_data = {}
# so here create a new file with multiple rows
# where "attribute to change" is the attribute modified
# here between 5 and 95 in steps of 5
for i in range(5, 100, 5):
with open(file_name) as data_file:
data = json.load(data_file)
# give the new row a unique id_num
data[str(id_num)] = data.pop('1')
generate_config_file(data[str(id_num)], 'attribute to change', i)
new_data[str(id_num)] = data[str(id_num)]
#json.dump(data, out_file, sort_keys=True, indent=4)
id_num += 1
json.dump(new_data, out_file, sort_keys=True, indent=4)
然后将其转储
答案 1 :(得分:0)
您正在谈论“行”,但您希望这样的字典结构(这是一个有效的 JSON文件):
{
"1": {},
"2": {},
"3": {}
}
所以我认为最好忘记“行”并总是考虑字典键值对,主要是因为“行”不是JSON standard的一部分,请同时查看validator。
在循环中使用:
json.dump(data, out_file, sort_keys=True, indent=4)
在这里以增量模式打开输出文件:
out_file = open('new config file.JSON', "a")`)
转换为将多个对象堆叠到output.json文本文件中, 这会创建一个无效 JSON文件,就像你指出的那样。
为了避免这种情况,您可以将字典结构一次性写入文件,为此,您可以更改示例代码的第二部分,如下所示:
# parse old config
with open(file_name, "r") as data_file:
data = json.load(data_file)
# set the new value of attribute_to_change for the first object in json
i = 5
# loop through top level object or what you call rowss
for key in sorted(data.keys()):
# update the attribute with recursive function on each top level
# object with an increasing value i
generate_config_file(data[key], 'attribute to change', i)
i += 5
# if you have 19 objects inside your root object in input json
# the value will span from 5 to 95
# save the whole modified "data" dictionary in one shot
out_file_name = 'new config file.JSON'
with open(out_file_name, "w") as out_file:
json.dump(data, out_file, sort_keys=True, indent=4)