簡體   English   中英

Python 迭代嵌套列表字典

[英]Python Iterate over nested list dictionaries

我有以下 json 內容,從 REST API 請求返回,我正在嘗試迭代內容並希望打印每個:對。 我知道我可以簡單地使用 print(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
      }
    }
  ]

您可以像這樣遞歸迭代

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)

Output

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}")

Output

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

你可以遞歸地得到對

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=[]))

output 應如下所示:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM