python - 从字典列表中动态创建嵌套 json 对象

标签 python python-3.x list

我想将字典列表转换为嵌套 JSON。我想动态填充字段。我想将所有信号分组为特定类别。我尝试了不同的方法,但无法生成所需的确切格式。需要一些逻辑帮助来生成 JSON

我的意见

signal_list = [
    {'sig_id': 667, 'sig_name': 'RotorSpeed', 'Category': 'Gbox'},
    {'sig_id': 672, 'sig_name': 'GeneratorSpeed', 'Category': 'Genarator'},
    {'sig_id': 673, 'sig_name': 'NacelleSpeed', 'Category': 'Nacelle'},
    {'sig_id': 668, 'sig_name': 'RotorDirection', 'Category': 'Gbox'}
]

我尝试过的代码:

d = defaultdict(list)
for t in signals:
    field_list = d[t['Category']]
    new_d = {'sig_name': t['sig_name'], 'sig_id': t['sig_id'], 'Category': t['Category']}
    field_list.append(defaultdict(list, new_d))

电流输出

[
   {
      "Gbox":[
         {
            "sig_name":"RotorSpeed",
            "sig_id":667
         },
         {
            "sig_name":"RotorDirection",
            "sig_id":668
         }
      ]
   },
   {
      "Genarator":[
         {
            "sig_name":"GeneratorSpeed",
            "sig_id":672
         }
      ]
   },
   {
      "Signals":[
         {
            "sig_name":"NacelleSpeed",
            "SignalID":673
         }
      ]
   }
]

(必需)我的输出应如下所示

[
   {
      "Category":"Gbox",
      "Signals":[
         {
            "sig_name":"RotorSpeed",
            "sig_id":667
         },
         {
            "sig_name":"RotorDirection",
            "sig_id":668
         }
      ]
   },
   {
      "Category":"Genarator",
      "Signals":[
         {
            "sig_name":"GeneratorSpeed",
            "sig_id":672
         }
      ]
   },
   {
      "Category":"Nacelle",
      "Signals":[
         {
            "sig_name":"NacelleSpeed",
            "SignalID":673
         }
      ]
   }
]

最佳答案

请参阅 itertools 文档,特别是 groupby功能。

import json
import itertools

dta = signal_list = [
    {'sig_id': 667, 'sig_name': 'RotorSpeed', 'Category': 'Gbox'},
    {'sig_id': 672, 'sig_name': 'GeneratorSpeed', 'Category': 'Genarator'},
    {'sig_id': 673, 'sig_name': 'NacelleSpeed', 'Category': 'Nacelle'},
    {'sig_id': 668, 'sig_name': 'RotorDirection', 'Category': 'Gbox'}
]

# this key is simply to be used on each dictionary to get the 'Category'
key = lambda dct: dct.get('Category')

# group works best with a sorted iterable. So let's sort by "Category' since that's
# your grouping key.
a = itertools.groupby(sorted(dta, key=key), key)

# groupby returns a generator like object that has tuples of (key, value)
# the value is also a generator like object that just has each item from the iterable
# that matches your grouping key. To get all the items we just turn them into a list
b = [{"Category": k, "Signals": list(v)} for k,v in a]

# using json to print it out in a nice format
print(json.dumps(b, indent=1))

输出:

[
 {
  "Category": "Gbox",
  "Signals": [
   {
    "sig_id": 667,
    "sig_name": "RotorSpeed",
    "Category": "Gbox"
   },
   {
    "sig_id": 668,
    "sig_name": "RotorDirection",
    "Category": "Gbox"
   }
  ]
 },
 {
  "Category": "Genarator",
  "Signals": [
   {
    "sig_id": 672,
    "sig_name": "GeneratorSpeed",
    "Category": "Genarator"
   }
  ]
 },
 {
  "Category": "Nacelle",
  "Signals": [
   {
    "sig_id": 673,
    "sig_name": "NacelleSpeed",
    "Category": "Nacelle"
   }
  ]
 }
]

如果我理解正确,您希望从列表中的每个词典中删除类别键。你可以这样做。如果您想删除多个键,只需编辑该函数并在内部执行某种循环:)

def remove_key(dct:dict, key):
    """
    Simply takes a dictionary, copies it and remove the key of interest
    from the copy and returns the copy.
    """
    # This function will be used in a list comprehension so it has to
    # return the dictionary and not just pop the key

    dct_ = dct.copy()
    _ = dct_.pop(key)

    return dct_

b = [{"Category": k, "Signals": [remove_key(dct, 'Category') for dct in v]} for k,v in a]

print(json.dumps(b, indent=1))

输出

[
 {
  "Category": "Gbox",
  "Signals": [
   {
    "sig_id": 667,
    "sig_name": "RotorSpeed"
   },
   {
    "sig_id": 668,
    "sig_name": "RotorDirection"
   }
  ]
 },
 {
  "Category": "Genarator",
  "Signals": [
   {
    "sig_id": 672,
    "sig_name": "GeneratorSpeed"
   }
  ]
 },
 {
  "Category": "Nacelle",
  "Signals": [
   {
    "sig_id": 673,
    "sig_name": "NacelleSpeed"
   }
  ]
 }
]

关于python - 从字典列表中动态创建嵌套 json 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58530517/

相关文章:

python - 我如何从 os.listdir 结果中排除目录?

python-3.x - asyncio 实现了什么样的事件驱动处理模式?

java - 如何使用 java JDBC 获取 MySql 的数据库 "Schema"名称列表

连接本地MySQL数据库的Python 3.2脚本

python - 从 PIL 获取像素值列表

python-3.x - spark-submit 无法检测到 pip 中安装的模数

c++ - 如何从该列表的元素中获取 std::list<T>::iterator?

python - 从字符串列表中指定索引处删除不需要的子字符串

python - Informixdb 多个连接

python - conda 环境 pip 正在尝试全局安装依赖项