June
June

Reputation: 730

Search for dictionary key, values that match in nested dictionary, wrapped in a list

consider this list:

d1  = [{'data': {'id': '1', 'label': 'ID #1', 'expanded': True}, 'classes': 'genesis'}, {'data': {'id': '2', 'label': 'ID #2', 'expanded': True}, 'classes': 'followerNode'}, {'data': {'id': '3', 'label': 'ID #3'}, 'classes': 'followerNode'}, {'data': {'id': '4', 'label': 'ID #4'}, 'classes': 'followerNode'}, {'data': {'id': '5', 'label': 'ID #5'}, 'classes': 'followerNode'}, {'data': {'id': '6', 'label': 'ID #6'}, 'classes': 'followerNode'}, {'data': {'id': '7', 'label': 'ID #7'}, 'classes': 'followerNode'}, {'data': {'id': '21', 'source': '2', 'target': '1'}, 'classes': 'followerEdge'}, {'data': {'id': '31', 'source': '3', 'target': '1'}, 'classes': 'followerEdge'}, {'data': {'id': '41', 'source': '4', 'target': '1'}, 'classes': 'followerEdge'}, {'data': {'id': '51', 'source': '5', 'target': '1'}, 'classes': 'followerEdge'}, {'data': {'id': '61', 'source': '6', 'target': '1'}, 'classes': 'followerEdge'}, {'data': {'id': '71', 'source': '7', 'target': '1'}, 'classes': 'followerEdge'}, {'data': {'id': '8', 'label': 'ID #8'}, 'classes': 'followerNode'}, {'data': {'id': '13', 'label': 'ID #13'}, 'classes': 'followerNode'}, {'data': {'id': '14', 'label': 'ID #14'}, 'classes': 'followerNode'}, {'data': {'id': '15', 'label': 'ID #15'}, 'classes': 'followerNode'}, {'data': {'id': '18', 'label': 'ID #18'}, 'classes': 'followerNode'}, {'data': {'id': '19', 'label': 'ID #19'}, 'classes': 'followerNode'}, {'data': {'id': '20', 'label': 'ID #20'}, 'classes': 'followerNode'}, {'data': {'id': '82', 'source': '8', 'target': '2'}, 'classes': 'followerEdge'}, {'data': {'id': '132', 'source': '13', 'target': '2'}, 'classes': 'followerEdge'}, {'data': {'id': '142', 'source': '14', 'target': '2'}, 'classes': 'followerEdge'}, {'data': {'id': '152', 'source': '15', 'target': '2'}, 'classes': 'followerEdge'}, {'data': {'id': '182', 'source': '18', 'target': '2'}, 'classes': 'followerEdge'}, {'data': {'id': '192', 'source': '19', 'target': '2'}, 'classes': 'followerEdge'}, {'data': {'id': '202', 'source': '20', 'target': '2'}, 'classes': 'followerEdge'}, {'data': {'id': '8', 'label': 'ID #8'}, 'classes': 'followerNode'}, {'data': {'id': '13', 'label': 'ID #13'}, 'classes': 'followerNode'}, {'data': {'id': '14', 'label': 'ID #14'}, 'classes': 'followerNode'}, {'data': {'id': '15', 'label': 'ID #15'}, 'classes': 'followerNode'}, {'data': {'id': '18', 'label': 'ID #18'}, 'classes': 'followerNode'}, {'data': {'id': '19', 'label': 'ID #19'}, 'classes': 'followerNode'}, {'data': {'id': '20', 'label': 'ID #20'}, 'classes': 'followerNode'}, {'data': {'id': '82', 'source': '8', 'target': '2'}, 'classes': 'followerEdge'}, {'data': {'id': '132', 'source': '13', 'target': '2'}, 'classes': 'followerEdge'}, {'data': {'id': '142', 'source': '14', 'target': '2'}, 'classes': 'followerEdge'}, {'data': {'id': '152', 'source': '15', 'target': '2'}, 'classes': 'followerEdge'}, {'data': {'id': '182', 'source': '18', 'target': '2'}, 'classes': 'followerEdge'}, {'data': {'id': '192', 'source': '19', 'target': '2'}, 'classes': 'followerEdge'}, {'data': {'id': '202', 'source': '20', 'target': '2'}, 'classes': 'followerEdge'}]

how do I search for say "1" when there are other key types (like 'source' or 'target'):

I want to remove the sub dict which matches any of my search criteria... for instance id with val of 1... it should remove this:

{'data': {'id': '1', 'label': 'ID #1', 'expanded': True}, 'classes': 'genesis'}

Here's what I tried:

[{k:v} for lst in d1 for k, v in lst.items() if (("1" not in (v.get('source', None), (v!=None))) and 
            ("1" not in (v.get('target', None), (v!=None))) and
            ("1" not in (v.get('id', None), (v!=None))))]

but I'm getting

AttributeError: 'str' object has no attribute 'get'

Upvotes: 2

Views: 1106

Answers (2)

Pranav Yeola
Pranav Yeola

Reputation: 26

In your code the "for k,v in lst.items()" gives k,v as 'data','classes' hence it gives the attribute error.

To get dictionary with required Id:

ans = []
ID = '1'
for k in d1:
    if k['data']['id'] == ID:
        ans.append(k)

Upvotes: 0

goalie1998
goalie1998

Reputation: 1432

Each item in your list had dictionary with two key-value pairs, the first had a dictionary as the value, the second a string. When you looped through for k, v in lst.items() on each item in the list, it would work find on the first key-value pair, but for the second key-value pair it would see a string as the value, not a dictionary which is what caused the issue.

I think this should do the trick:

[lst for lst in d1 if "1" not in lst["data"].get('source', "None")
    and "1" not in lst["data"].get('target', "None")
    and "1" not in lst["data"].get('id', "None")]

or

for lst in d1:
    if "1" not in lst["data"].get('source', "None")\
            and "1" not in lst["data"].get('target', "None")\
            and "1" not in lst["data"].get('id', "None"):
        lst

Upvotes: 1

Related Questions