Python Recursive Search of Dict with Nested Keys

2024/10/5 1:22:59

I recently had to solve a problem in a real data system with a nested dict/list combination. I worked on this for quite a while and came up with a solution, but I am very unsatisfied. I had to resort to using globals() and a named temporary global parameter.

I do not like to use globals. That's just asking for an injection vulnerability. I feel that there must be a better way to perform this task without resorting to globals.

Problem Dataset:

d = {"k":1,"stuff":"s1","l":{"m":[{"k":2,"stuff":"s2","l":None},{"k":3,"stuff":"s3","l":{"m":[{"k":4,"stuff":"s4","l":None},{"k":5,"stuff":"s5","l":{"m":[{"k":6,"stuff":"s6","l":None},]}},]}},]}
}

Desired Output:

[{'k': 1, 'stuff': 's1'},{'k': 2, 'stuff': 's2'},{'k': 3, 'stuff': 's3'},{'k': 4, 'stuff': 's4'},{'k': 5, 'stuff': 's5'},{'k': 6, 'stuff': 's6'}]

My Solution:

def _get_recursive_results(d, iter_key, get_keys):if not 'h' in globals():global hh = []h.append({k:d.get(k) for k in get_keys})d2 = d.copy()for k in iter_key:if not d2:continued2 = d2.get(k)for td in d2:d3 = td.copy()for k in iter_key:if not d3:continued3 = d3.get(k)if d3:return _get_recursive_results(td, iter_key, get_keys)h.append({k:td.get(k) for k in get_keys})else:l = [k for k in h]del globals()['h']return l

Calling my function as follows returns the desired result:

_get_recursively(d, ['l','m'], ['k','stuff'])

How would I build a better solution?

Answer

This is a slightly modified version without using globals. Set h to None as default and create a new list for the first call to _get_recursive_results(). Later provide h as an argument in the recursive calls to _get_recursive_results():

def _get_recursive_results(d, iter_key, get_keys, h=None):if h is None:h = []h.append({k:d.get(k) for k in get_keys})d2 = d.copy()for k in iter_key:if not d2:continued2 = d2.get(k)for td in d2:d3 = td.copy()for k in iter_key:if not d3:continued3 = d3.get(k)if d3:return _get_recursive_results(td, iter_key, get_keys, h)h.append({k:td.get(k) for k in get_keys})else:l = [k for k in h]return l

Now:

>>> _get_recursive_results(d, ['l','m'], ['k','stuff'])
[{'k': 1, 'stuff': 's1'},{'k': 2, 'stuff': 's2'},{'k': 3, 'stuff': 's3'},{'k': 4, 'stuff': 's4'},{'k': 5, 'stuff': 's5'},{'k': 6, 'stuff': 's6'}]

There is no need for the copying of intermediate dicts. This is a further modified version without copying:

def _get_recursive_results(d, iter_key, get_keys, h=None):if h is None:h = []h.append({k: d.get(k) for k in get_keys})for k in iter_key:if not d:continued = d.get(k)for td in d:d3 = tdfor k in iter_key:if not d3:continued3 = d3.get(k)if d3:return _get_recursive_results(td, iter_key, get_keys, h)h.append({k: td.get(k) for k in get_keys})else:return h
https://en.xdnf.cn/q/70544.html

Related Q&A

Scrapy: how to catch download error and try download it again

During my crawling, some pages failed due to unexpected redirection and no response returned. How can I catch this kind of error and re-schedule a request with original url, not with the redirected url…

Cryptacular is broken

this weekend our docker image broke because it cannot be build anymore. While looking into the stats, I saw this line:crypt_blowfish-1.2/crypt.h:17:23: fatal error: gnu-crypt.h: No such file or directo…

how to run test against the built image before pushing to containers registry?

From the gitlab documentation this is how to create a docker image using kaniko: build:stage: buildimage:name: gcr.io/kaniko-project/executor:debugentrypoint: [""]script:- mkdir -p /kaniko/.d…

Adding a colorbar to a pcolormesh with polar projection

I am trying to add a colorbar to a pcolormesh plot with polar projection. The code works fine if I dont specify a polar projection. With polar projection specified, a tiny plot results, and the colorba…

GridSearch for Multi-label classification in Scikit-learn

I am trying to do GridSearch for best hyper-parameters in every individual one of ten folds cross validation, it worked fine with my previous multi-class classification work, but not the case this time…

Visualize tree in bash, like the output of unix tree

Given input:apple: banana eggplant banana: cantaloupe durian eggplant: fig:I would like to concatenate it into the format:├─ apple │ ├─ banana │ │ ├─ cantaloupe │ │ └─ durian │ └…

pygame.error: Failed loading libmpg123.dll: Attempt to access invalid address

music = pygame.mixer.music.load(not.mp3) pygame.mixer.music.play(loops=-1)when executing the code I got this error: Traceback (most recent call last):File "C:\Users\Admin\AppData\Local\Programs\Py…

Plot Red Channel from 3D Numpy Array

Suppose that we have an RGB image that we have converted it to a Numpy array with the following code:import numpy as np from PIL import Imageimg = Image.open(Peppers.tif) arr = np.array(img) # 256x256x…

How to remove image noise using opencv - python?

I am working with skin images, in recognition of skin blemishes, and due to the presence of noises, mainly by the presence of hairs, this work becomes more complicated.I have an image example in which …

Django groups and permissions

I would like to create 2 groups (Professors, Students). And I would like to restrict students from creating and deleting Courses.views.py:def is_professor(function=None):def _is_professor(u):if user.gr…