change198
change198

Reputation: 2065

How to find a dict in a list with a particular key?

I have a list of lists with dicts as below:

[{'key': 'Platform', 'value': 'Test'}, {'key': 'Name', 'value': 'Test1'}, {'key': 'APICall', 'value': 'post'}]
[{'key': 'Platform', 'value': 'Test1'}, {'key': 'APICall', 'value': 'Get'}]
[{'key': 'Platform', 'value': 'Test2'}, {'key': 'Name', 'value': 'Test2'}, {'key': 'APICall', 'value': 'post'}]

for this list I would like to get the lists if keys Platform and Name are present. So I would like to get [{'key': 'Platform', 'value': 'Test'}, {'key': 'Name', 'value': 'Test1'}, {'key': 'APICall', 'value': 'post'}] and [{'key': 'Platform', 'value': 'Test2'}, {'key': 'Name', 'value': 'Test2'}, {'key': 'APICall', 'value': 'post'}]

I don't know how to achieve this in one most effective way? I did a very simplistic way which is working, but in the future, if the list count grows then it might take a longer time. Is there any simple and effective way to achieve this?

for arr_keys in arr:
    if arr_keys['key'] == "Platform":
        platform = arr_keys['value']
    if arr_keys['key'] == "Name":
        Name = arr_keys['value']

Upvotes: 0

Views: 63

Answers (2)

Tomerikoo
Tomerikoo

Reputation: 19414

So for each list, you want to check if all the keys (Platform and Name) appear in any of the dicts. This directly translates to:

lists = [[{'key': 'Platform', 'value': 'Test'}, {'key': 'Name', 'value': 'Test1'}, {'key': 'APICall', 'value': 'post'}],
         [{'key': 'Platform', 'value': 'Test1'}, {'key': 'APICall', 'value': 'Get'}],
         [{'key': 'Platform', 'value': 'Test2'}, {'key': 'Name', 'value': 'Test2'}, {'key': 'APICall', 'value': 'post'}]]

for obj in lists:
    if all(any(d["key"] == key for d in obj) for key in ("Platform", "Name")):
        print(obj)

This will however iterate over the dicts for each key. To do it in one pass over the dicts, something like this can work, using a defaultdict:

from collections import defaultdict

keys = ("Platform", "Name")
for obj in lists:
    seen = defaultdict(bool)
    for d in obj:
        seen[d["key"]] = True

    if all(seen[key] for key in keys):
        print(obj)

Upvotes: 1

big_bad_bison
big_bad_bison

Reputation: 1015

The only improvement you can make without changing the formatting of the input is to break out of the loop once the keys 'Platform' and 'Name' are encountered.

platform = None
name = None
for arr_keys in arr:
    if arr_keys['key'] == "Platform":
        platform = arr_keys['value']
    if arr_keys['key'] == "Name":
        name = arr_keys['value']
    if platform is not None and name is not None:
        print(arr)
        break

Upvotes: 1

Related Questions