且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用Python将值插入json文件中的特定位置

更新时间:2023-10-09 12:50:04

没有"json对象"之类的东西-json只是一种序列化/反序列化常见数据类型(字符串,数字,数组和关联数据)的方法数组).在您的Python代码中,您所拥有的只是Python对象,在您的情况下,一个包含字典的列表(名为JsonObject)本身包含列表和字典,除了普通的基本Python数据类型,这里真的没有什么特别需要了解的.

当然,jsonObject列表中的所有列表方法都不会在这里使用,因为要存储文件列表的对象是您刚刚追加到列表的字典,而不是列表本身.

解决方案很明显:只需将文件列表添加到元素中 之前(或何时),将其添加到主列表中即可,即:

if files:
    elementId = basename(normpath(path)) + "Audio" 
    element = { 
      "elementId" : elementId, 
      "params" : { 
         "audioPath" : path, 
         "sounds" : list(files)
         },
      }
    jsonObject.append(element)

或更简单地说:

if files:
    elementId = basename(normpath(path)) + "Audio" 
    jsonObject.append({ 
      "elementId" : elementId, 
      "params" : { 
         "audioPath" : path, 
         "sounds" : list(files)
         },
      })

Trying to find an elegant way to insert filenames from a os.walk() loop into a specific sub-element (for want of a better term) in a Python object that will be output as a JSON file. If that does not make much sense, here are some visual output of what I've cobbled together so far.

code used:

import os
from os.path import normpath, basename
import json

ROOT_PATH = "sounds/"
jsonObject = []

for path, subdirs, files in os.walk(ROOT_PATH):
   if files:
      elementId = basename(normpath(path)) + "Audio" # <-- builds custom Id based on path
      jsonObject.append( { "elementId" : elementId, "params" : { "audioPath" : path, "sounds" : [] } } )
      for name in files:
         jsonObject.append(name)  #  <-- problem lies here...

with open('sounds/Elements.json', 'w') as outfile:
   json.dump(jsonObject, outfile, indent=3, ensure_ascii=False, sort_keys=True)

...which produces:

[
   {
      "elementId": "soundsAudio",
      "params": {
         "audioPath": "sounds/",
         "sounds": []
      }
   },
   "beep2.mp3",
   "heart_rate_flatline.mp3",
   "shhh.mp3",
   {
      "elementId": "aha_aedAudio",
      "params": {
         "audioPath": "sounds/aha_aed",
         "sounds": []
      }
   },
   "AnalyzingHeartRhythm.mp3",
   "AttachPadsToPatientsBareChest.mp3",
   "BeginCPR.mp3",
   "Charging.mp3",
   "DoNotTouchThePatient.mp3"
]

...and this is really close. But I've run into a brain block getting the list of mp3 files into the sounds section, so that it looks like this:

[
   {
      "elementId": "soundsAudio",
      "params": {
         "audioPath": "sounds/",
         "sounds": [ "beep2.mp3",
                     "heart_rate_flatline.mp3",
                     "shhh.mp3"
         ]
      }
   },
   {
      "elementId": "aha_aedAudio",
      "params": {
         "audioPath": "sounds/aha_aed",
         "sounds": [ "AnalyzingHeartRhythm.mp3",
                     "AttachPadsToPatientsBareChest.mp3",
                     "BeginCPR.mp3",
                     "Charging.mp3",
                     "DoNotTouchThePatient.mp3"
         ]
      }
   }
]

.append, .extend, and .insert are letting me down at this point (or maybe I'm not using them properly), and doing an overly complex regex search-n-replace-copy-n-paste operation for the sounds element feels...dirty somehow.

I realize I may be resigned to doing that anyway before outputting the whole thing into a JSON file. Any thoughts, tips, or solution examples I can absorb would be greatly appreciated!

There's no such thing as a "json object" - json is just a way to serialize / deserialize common data types (strings, nums, arrays and associative arrays). All you have in your Python code are Python objects, in your case a list (named JsonObject) containing dicts which themselves contains lists and dicts, really nothing special to know here except plain basic Python datatypes.

Of course none of the list methods of your jsonObject list will be of any use here since the object you want to store your files list into is the dict you just appended to the list, not the list itself.

The solution is obvious: just add the files list to your element before (or when) you append it to your main list, ie:

if files:
    elementId = basename(normpath(path)) + "Audio" 
    element = { 
      "elementId" : elementId, 
      "params" : { 
         "audioPath" : path, 
         "sounds" : list(files)
         },
      }
    jsonObject.append(element)

or more simply:

if files:
    elementId = basename(normpath(path)) + "Audio" 
    jsonObject.append({ 
      "elementId" : elementId, 
      "params" : { 
         "audioPath" : path, 
         "sounds" : list(files)
         },
      })