182 lines
5.3 KiB
Python
182 lines
5.3 KiB
Python
from six import iteritems
|
|
|
|
from collections import defaultdict
|
|
|
|
|
|
values_list = []
|
|
|
|
|
|
def nested_lookup(key, document, wild=False, with_keys=False):
|
|
"""Lookup a key in a nested document, return a list of values"""
|
|
if with_keys:
|
|
d = defaultdict(list)
|
|
for k, v in _nested_lookup(key, document, wild=wild, with_keys=with_keys):
|
|
d[k].append(v)
|
|
return d
|
|
return list(_nested_lookup(key, document, wild=wild, with_keys=with_keys))
|
|
|
|
|
|
def _is_case_insensitive_substring(a, b):
|
|
"""return True if `a` is a case insensitive substring of `b`, else False"""
|
|
return str(a).lower() in str(b).lower()
|
|
|
|
|
|
def _nested_lookup(key, document, wild=False, with_keys=False):
|
|
"""Lookup a key in a nested document, yield a value"""
|
|
if isinstance(document, list):
|
|
for d in document:
|
|
for result in _nested_lookup(key, d, wild=wild, with_keys=with_keys):
|
|
yield result
|
|
|
|
if isinstance(document, dict):
|
|
for k, v in iteritems(document):
|
|
if key == k or (wild and _is_case_insensitive_substring(key, k)):
|
|
if with_keys:
|
|
yield k, v
|
|
else:
|
|
yield v
|
|
if isinstance(v, dict):
|
|
for result in _nested_lookup(key, v, wild=wild, with_keys=with_keys):
|
|
yield result
|
|
elif isinstance(v, list):
|
|
for d in v:
|
|
for result in _nested_lookup(
|
|
key, d, wild=wild, with_keys=with_keys
|
|
):
|
|
yield result
|
|
|
|
|
|
def get_all_keys(dictionary):
|
|
"""
|
|
Method to get all keys from a nested dictionary as a List
|
|
Args:
|
|
dictionary: Nested dictionary
|
|
Returns:
|
|
List of keys in the dictionary
|
|
"""
|
|
result_list = []
|
|
|
|
def recrusion(document):
|
|
if isinstance(document, list):
|
|
for list_items in document:
|
|
recrusion(document=list_items)
|
|
elif isinstance(document, dict):
|
|
for key, value in iteritems(document):
|
|
result_list.append(key)
|
|
recrusion(document=value)
|
|
return
|
|
|
|
recrusion(document=dictionary)
|
|
return result_list
|
|
|
|
|
|
def get_occurrence_of_key(dictionary, key):
|
|
"""
|
|
Method to get occurrence of a key in a nested dictionary
|
|
|
|
Args:
|
|
dictionary: Nested dictionary
|
|
key: Key to search for the occurrences
|
|
Return:
|
|
Number of occurrence (Integer)
|
|
"""
|
|
return _get_occurrence(dictionary=dictionary, item="key", keyword=key)
|
|
|
|
|
|
def get_occurrence_of_value_with_self_value(items: list, value: any) -> dict:
|
|
"""
|
|
Method to get occurrence of a value in a nested list of dictionary
|
|
|
|
Args:
|
|
items: list of dictionary: Nested dictionary
|
|
value: Value to search for the occurrences
|
|
|
|
Return:
|
|
Dict where the key is the value arg and his value is a new
|
|
dict with occurrences and values
|
|
"""
|
|
occurrences = {}
|
|
occurrence = 0
|
|
value_list = []
|
|
|
|
for item in items:
|
|
occurrence_result, values = _get_occurrence_with_values(dictionary=item, item="value", keyword=value)
|
|
occurrence = occurrence + occurrence_result
|
|
if occurrence_result:
|
|
value_list.extend(values)
|
|
|
|
occurrences[value] = {
|
|
'occurrences': occurrence,
|
|
'values': value_list
|
|
}
|
|
|
|
return occurrences
|
|
|
|
|
|
def _get_occurrence_with_values(dictionary, item, keyword):
|
|
occurrence = [0]
|
|
|
|
result_recursion = recursion(dictionary, item, keyword, occurrence, True)
|
|
|
|
global values_list
|
|
values_list = []
|
|
|
|
return occurrence[0], result_recursion
|
|
|
|
|
|
def get_occurrence_of_value(dictionary, value):
|
|
"""
|
|
Method to get occurrence of a value in a nested dictionary
|
|
|
|
Args:
|
|
dictionary: Nested dictionary
|
|
value: Value to search for the occurrences
|
|
Return:
|
|
Number of occurrence (Integer)
|
|
"""
|
|
return _get_occurrence(dictionary=dictionary, item="value", keyword=value)
|
|
|
|
|
|
def recursion(dictionary, item, keyword, occurrence, with_values=False):
|
|
|
|
global values_list
|
|
|
|
if item == "key":
|
|
if dictionary.get(keyword) is not None:
|
|
occurrence[0] += 1
|
|
elif keyword in list(dictionary.values()):
|
|
occurrence[0] += list(dictionary.values()).count(keyword)
|
|
if with_values:
|
|
values_list.append(dictionary)
|
|
for key, value in iteritems(dictionary):
|
|
if isinstance(value, dict):
|
|
recursion(value, item, keyword, occurrence, with_values)
|
|
elif isinstance(value, list):
|
|
for list_items in value:
|
|
if hasattr(list_items, "items"):
|
|
recursion(list_items, item, keyword, occurrence, with_values)
|
|
elif list_items == keyword:
|
|
occurrence[0] += 1 if item == "value" else 0
|
|
|
|
if values_list:
|
|
return values_list
|
|
|
|
|
|
def _get_occurrence(dictionary, item, keyword):
|
|
"""
|
|
Method to get occurrence of a key or value in a nested dictionary
|
|
|
|
Args:
|
|
dictionary: Nested dictionary
|
|
item: Mostly (key or value)
|
|
keyword: key word to find occurrence
|
|
Return:
|
|
Number of occurrence of the given keyword in the dict
|
|
"""
|
|
occurrence = [0]
|
|
recursion(dictionary, item, keyword, occurrence)
|
|
|
|
global values_list
|
|
values_list = []
|
|
|
|
return occurrence[0]
|