【问题标题】:Python Iterate over nested list dictionariesPython迭代嵌套列表字典
【发布时间】:2021-12-29 19:54:33
【问题描述】:

我有以下 json 内容,从 REST API 请求返回,我正在尝试迭代内容并希望打印每个 : 对。我知道我可以简单地使用 打印(json.dumps(config, indent=4))

然而,我想弄清楚如何构造嵌套循环以用于迭代键。我首先假设我有一个字典列表,即。遍历列表,然后遍历列表中的每个字典并打印 ;一对。但是,每个字典中都有列表,这些列表中也包含字典。

[
    {
      "name": "<name>",
      "snippets": [
        {
          "name": "show_processes",
          "label": "Show Processes",
          "sql": "SELECT * FROM system.runtime",
          "can": {}
        }
      ],
      "host": "<host-url>",
      "port": "<port>",
      "database": "<database>",
      "db_timezone": null,
      "query_timezone": null,
      "schema": "<schema>",
      "after_connect_statements": null,
      "dialect": {
        "supports_cost_estimate": false,
        "automatically_run_sql_runner_snippets": true,
        "connection_tests": [
          "connect",
          "kill",
          "database_timezone",
          "database_version",
          "tmp_db",
          "cdt",
          "tmp_db_views"
        ],
        "supports_inducer": false,
        "supports_multiple_databases": false,
        "supports_persistent_derived_tables": true,
        "has_ssl_support": true,
        "name": "mike",
        "label": "<db>",
        "supports_streaming": true
      },
      "dialect_name": "sql",
      "example": false,
      "managed": false,
      "username": "<username>",
      "uses_oauth": false,
      "tunnel_id": null,
      "can": {
        "index": true,
        "index_limited": true,
        "show": true
      }
    },
    {
      "name": "<name>",
      "snippets": [],
      "host": "<host_url>",
      "port": "<port>",
      "database": "<db>",
      "db_timezone": null,
      "query_timezone": null,
      "schema": null,
      "after_connect_statements": null,
      "dialect": {
        "supports_cost_estimate": false,
        "connection_tests": [
          "connect",
          "query"
        ],
        "supports_inducer": false,
        "supports_multiple_databases": false,
        "has_ssl_support": true,
        "name": "<name>",
        "label": "<dbName>"
      },
      "dialect_name": "<dbType>",
      "example": false,
      "managed": false,
      "username": "<username>",
      "tunnel_id": null,
      "can": {
        "index": true,
        "index_limited": true,
        "show": true
      }
    },
    {
      "name": "<name>",
      "snippets": [
        {
          "name": "show_processes",
          "label": "Show Processes",
          "sql": "SHOW PROCESSLIST",
          "can": {}
        }
      ],
      "host": "<host-url>",
      "port": "<port>",
      "database": "<db>",
      "db_timezone": null,
      "query_timezone": null,
      "schema": null,
      "after_connect_statements": null,
      "dialect": {
        "supports_cost_estimate": false,
        "automatically_run_sql_runner_snippets": true,
        "connection_tests": [
          "connect",
          "kill",
          "query",
          "database_timezone",
          "database_version",
          "tmp_db",
          "mysql_tmp_tables",
          "cdt",
          "tmp_db_views"
        ],
        "supports_inducer": false,
        "supports_multiple_databases": false,
        "has_ssl_support": true,
        "name": "<name>",
        "label": "dbName>",
        "supports_streaming": true,
      },
      "dialect_name": "<dbType>",
      "example": false,
      "managed": false,
      "username": "<username>",
      "tunnel_id": null,
      "can": {
        "index": true,
        "index_limited": true,
        "show": true
      }
    }
  ]

【问题讨论】:

  • 你能解释一下你所说的pair是什么意思吗?
  • 配对,打印,即。 “位置”:“圣地亚哥”。打印键是位置,值是圣地亚哥
  • 明白了,看我贴的答案,递归就可以得到。

标签: python json loops


【解决方案1】:

你可以像这样递归迭代

import json


def iterate_json(obj, depth=0, callback=None):
    if isinstance(obj, list):
        # Handle list case
        for idx, nested_obj in enumerate(obj):
            print("\t" * depth + f"List #{idx}:")
            iterate_json(nested_obj, depth + 1, callback)

    elif isinstance(obj, dict):
        # Handle dict case
        print("\t" * depth + f"Dict:")
        for key, value in obj.items():
            print("\t" * depth + f"Key: {key}")
            iterate_json(value, depth + 1, callback)

    else:
        # it str, bool or None
        print("\t" * depth + f"Value: {obj}")
        
        # Here you can call your callback function to process JSON 
        callback(obj)

输出

List #0:
        Dict:
        Key: name
                Value: <name>
        Key: snippets
                List #0:
                        Dict:
                        Key: name
                                Value: show_processes
                        Key: label
                                Value: Show Processes
                        Key: sql
                                Value: SELECT * FROM system.runtime
                        Key: can
                                Dict:

如果你只想打印 str-str 对,你可以简化它


def iterate_json(obj):
    if isinstance(obj, list):
        # Handle list case
        for idx, nested_obj in enumerate(obj):
            iterate_json(nested_obj)

    elif isinstance(obj, dict):
        # Handle dict case
        for key, value in obj.items():
            if isinstance(value, list) or isinstance(value, dict):
                iterate_json(value)
            else:
                print(f"{key}: {value}")

输出

name: <name>
name: show_processes
label: Show Processes
sql: SELECT * FROM system.runtime
host: <host-url>
port: <port>
database: <database>
db_timezone: None
query_timezone: None
schema: <schema>
after_connect_statements: None
supports_cost_estimate: False
automatically_run_sql_runner_snippets: True
supports_inducer: False

【讨论】:

    【解决方案2】:

    你可以递归地得到对

    def get_pairs(d, pairs=[]):
        # if it is iterable, check pairs in each element
        if type(d) in [list, tuple, set]:
            for item in d:
                new_pairs = get_pairs(item, pairs)
                pairs.extend(new_pairs)
        
        # if it is a dict, check key values for pairs
        if isinstance(d, dict):
            for key, value in d.items():
                
                # if dict value is iterable, check pairs in each element
                if type(value) in [list, tuple, set]:
                    for item in value:
                        new_pairs = get_pairs(item, pairs)
                        pairs.extend(new_pairs)
                        
                # if it is a dict, get its pairs
                elif isinstance(value, dict):
                    get_pairs(value, pairs)
                    
                # otherwise, simply add key value as a new pair
                else:
                    pairs.append((key, value))
    
        return pairs
    
    print(get_pairs(data, pairs=[]))
    

    输出应如下所示:

    [('name', '<name>'),
     ('name', 'show_processes'),
     ('label', 'Show Processes'),
     ('sql', 'SELECT * FROM system.runtime'),
     ('name', '<name>'),
     ('name', 'show_processes'),
     ('label', 'Show Processes'),
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-02-22
      • 2014-01-21
      • 2012-07-15
      • 1970-01-01
      • 1970-01-01
      • 2011-10-14
      • 1970-01-01
      相关资源
      最近更新 更多