商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > Python 中使用循环与列表推导式提取 JSON 多层嵌套中的云主机名

Python 中使用循环与列表推导式提取 JSON 多层嵌套中的云主机名

  发布于2026-07-18 阅读(0)

扫一扫,手机访问

从Shell切到Python处理JSON,这事儿在实际项目中太常见了。jq命令虽然好用,但一旦需要集成到Python项目里,或者要批量处理几十个结构参差不齐的JSON文件,直接用Python原生解析显然更可控、更易维护。很多人卡在哪儿呢?SyntaxError: invalid syntax——说白了,就是Python不支持jq那种通配符索引[],必须老老实实遍历列表。
核心问题:如何在Python中替代jq '.cis[].properties.cloud_vm_display_name' | grep -v null这条命令,从多个结构不一的JSON文件中稳健提取cloud_vm_display_name字段值,同时避免语法错误和空值误判。

Python 中使用循环与列表推导式提取 JSON 多层嵌套中的云主机名

✅ 正确做法:遍历 data1['cis'] 列表

假设已经通过json.load()把单个JSON文件读成了字典data1,结构大概是这个样子:
{
  "cis": [
    {
      "properties": {
        "cloud_vm_display_name": "azuXXXXX",
        "TenantsUses": [ ... ]
      }
    },
    {
      "properties": {
        "cloud_vm_display_name": "null",
        ...
      }
    }
  ]
}
那么,正确的做法是安全遍历加显式空值检查。推荐两种写法,看场景选:
# 方案 1:基础 for 循环(清晰易调试)
vm_names = []
for cis_item in data1.get('cis', []):
    props = cis_item.get('properties', {})
    name = props.get('cloud_vm_display_name')
    # 注意:'null' 是字符串,不是 None;需区分 'null' 字面量 vs None/缺失值
    if name is not None and name != 'null':
        vm_names.append(name)
print(vm_names)  # ['azuXXXXX', 'azuXXXXXX', ...]
# 方案 2:简洁列表推导式(生产推荐)
vm_names = [
    cis['properties']['cloud_vm_display_name']
    for cis in data1.get('cis', [])
    if cis.get('properties', {}).get('cloud_vm_display_name') not in (None, 'null')
]
⚠️ 关键提醒:
  • if 'null' in name这种写法存在严重逻辑缺陷——它会错误过滤掉"anulled-server"或"nullified-db"这类合法名称;
  • grep -v null在Shell中实际匹配的是整行等于"null"的输出,Python中应严格比对== 'null'或检查is None
  • 更健壮的做法是使用.get(key, default)避免KeyError,尤其当某些cis条目可能缺失properties或cloud_vm_display_name字段时。

批量处理多个 JSON 文件

如果要对标原始命令cat * | jq ...,处理目录下所有.json文件,可以用glob加上异常处理:
import json
import glob

all_vm_names = []
for filepath in glob.glob("*.json"):
    try:
        with open(filepath, encoding='utf-8') as f:
            data = json.load(f)
        # 对每个文件提取 names
        names = [
            cis.get('properties', {}).get('cloud_vm_display_name')
            for cis in data.get('cis', [])
        ]
        # 过滤掉 None 和字符串 'null'
        valid_names = [n for n in names if n not in (None, 'null')]
        all_vm_names.extend(valid_names)
    except (json.JSONDecodeError, OSError) as e:
        print(f"跳过无效文件 {filepath}: {e}")

print(all_vm_names)

✅ 最佳实践总结

  • ❌ 避免if 'null' in name——语义错误,易误伤;
  • ✅ 使用name != 'null' and name is not Nonename not in (None, 'null')
  • ✅ 始终用.get()访问嵌套键,防止KeyError;
  • ✅ 批量处理时加入try/except,保障程序鲁棒性;
  • ✅ 若需完全复刻jq '.cis[].properties.cloud_vm_display_name | values'行为(自动跳过null/undefined),Python中等价逻辑即:仅保留非None且非'null'的字符串值。
掌握这种模式之后,你不仅能替代Shell加jq的流水线,还能轻松扩展——比如加上去重、排序、写入CSV,或者对接监控系统,真正实现自动化运维闭环。
本文转载于:https://www.php.cn/faq/2341309.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注