简体   繁体   中英

Fetch all dictionary if given key and value matches in from a list of dictionary

I want to fetch the dict from a list of dict if given value for key and values matches. Below are my input and expected output.

Input:

[
    {
        "sqlFile": "test.sql",
        "noOfStatements": 3,
        "allQueries": "queries",
        "sqlOperations": [
            {
                "type": "CreateTable",
                "objectName": "objectname1",
                "schemaName": null
            },
            {
                "type": "CreateTable",
                "objectName": "objectname2",
                "schemaName": null
            },
            {
                "type": "DROP",
                "objectName": "objectname3",
                "schemaName": null
            }
        ]
    }
]

Expected output:

[
            {
                "type": "CreateTable",
                "objectName": "objectname1",
                "schemaName": null
            },
            {
                "type": "CreateTable",
                "objectName": "objectname2",
                "schemaName": null
            }
]

json_data has the response and sql_operations has the above specified input. The below is not working as expected. I need help in identifying the problem to get the expected output.

for i in json_data:
        logger.debug("I is :: {} ".format(type(i)))
        sql_operations = i['sqlOperations']
        for j in sql_operations:
            logger.debug("J is :: {} ".format(type(j)))
            for k,v in j.items():
                if k == 'operationType' and v == 'REPLACE View':
                     logger.debug("Key is {} and Item is {}".format(k,v))

As a single list comprehension you could do

output = [d for i in json_data for d in i['sqlOperations'] if d['type'] == 'CreateTable']

or using standard for loops

output = []
for i in json_data:
    for d in i['sqlOperations']:
        if d['type'] == 'CreateTable':
            output.append(d)

Assuming you use json.load to get your input as a python list of dicts, can you do this using list comprehension?

for i in json_data:
    ops = i.get('sqlOperations', [])
    select_dicts = [d for d in ops if d.get('type') == 'CreateTable']
    new_list.extend(select_dicts)

new_list
[{'type': 'CreateTable', 'objectName': 'objectname1', 'schemaName': None}, 
{'type': 'CreateTable', 'objectName': 'objectname2', 'schemaName': None}]
x = """ [{
    "sqlFile":
    "test.sql",
    "noOfStatements":
    3,
    "allQueries":
    "queries",
    "sqlOperations": [{
        "type": "CreateTable",
        "objectName": "objectname1",
        "schemaName": null
    }, {
        "type": "CreateTable",
        "objectName": "objectname2",
        "schemaName": null
    }, {
        "type": "DROP",
        "objectName": "objectname3",
        "schemaName": null
    }]
}]"""
import json
x = json.loads(x)
a = x[0]["sqlOperations"][0:2]
print(json.dumps(a, indent=2))

output

[
  {
    "type": "CreateTable",
    "objectName": "objectname1",
    "schemaName": null
  },
  {
    "type": "CreateTable",
    "objectName": "objectname2",
    "schemaName": null
  }
]
final_data = []
for j in sql_operations:
    if j.get("type") == "CreateTable":
        final_data.append(j)

Note: null is not a valid keyword in Python. It should be None

Assuming this is a dict (despite null which would imply json data)...

I've taken the liberty of changing null to None as null will throw a NameError . The list comprehension here also produces a list of lists, so to get your output only the first element is selected, but it will work if there is more than one element in the input list.

json_data = [
    {
        "sqlFile": "test.sql",
        "noOfStatements": 3,
        "allQueries": "queries",
        "sqlOperations": [
            {
                "type": "CreateTable",
                "objectName": "objectname1",
                "schemaName": None
            },
            {
                "type": "CreateTable",
                "objectName": "objectname2",
                "schemaName": None
            },
            {
                "type": "DROP",
                "objectName": "objectname3",
                "schemaName": None
            }
        ]
    }
]

selected_data = [[v for v in jd['sqlOperations'] if v.get('type') == 'CreateTable'] for jd in json_data if jd.get('sqlOperations')]
print(selected_data[0])

Result

[{'type': 'CreateTable', 'objectName': 'objectname1', 'schemaName': None}, {'type': 'CreateTable', 'objectName': 'objectname2', 'schemaName': None}]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM