Created
June 27, 2014 18:11
-
-
Save darKoram/7a2109be1f0006bae89a to your computer and use it in GitHub Desktop.
Unfinished: dict_from_list_adaptor to convert easily from a list to a dict related to https://groups.google.com/forum/#!msg/ansible-project/TYbORkOM6Dw/5lusNmTIDzUJ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from collections import Counter | |
def dict_from_list_adaptor(key, _list, key_name=None, results_names=None, find_first=False): | |
'''Given a list-flattened dict, do a key value retrieval | |
Imagine a dictionary where every entry was {word: dictword, def: ditdef} instead of {dictword: dictdef} | |
eg. list_flattened_dict=[{word: apple, def: 'fruit...', noun: True},{word: ape, def: 'mamal of genus...', noun: True}] | |
We have to loop over entries in order to extract the definition turning a constant time | |
hash lookup of a dict into a linear time array scan for a list. | |
Basically, our data is stored in the wrong datastructure and we need an adaptor. | |
@key: key for which we wish to extract the value | |
@_list: list of dict entries to scan. We search for 'key' in the values of each dict entry of _list. | |
@key_name: If defined, only search for the requested key as the value | |
for the list key of this name. | |
@results_names: If defined, only return _list values whose keys are in resutls_names, | |
otherwise, return the entire matching entry in list. | |
@returns: a dict which is a subset of the matching item (list entry) with keys in results_names, | |
If results_names=None all key-value pairs besides the requested key are returned. | |
@throws: NonUniqueKeyException if the key is found more than once | |
@throws: NonUniqueKeyException when requesting a key that is the value in multiple | |
fields in the flattened dict. In the example above, the entry word: True would be a problem because | |
if we search for key=True we find it in multiple values. Using key_name avoids this. | |
''' | |
def return_results(key, list_entry_dict, results_names): | |
result=[] | |
for _key in list_entry_dict.keys(): | |
# add the key-value pair to the results | |
if _key != key: | |
result.append({_key: list_entry_dict[_key]}) | |
return result | |
results=[] | |
for item in _list: | |
if key_name: | |
if item[key_name] == key: | |
results.append(return_results(key, item, results_names)) | |
if find_first: | |
return results[0] | |
else: | |
if key in item.values(): | |
if Counter(item.values()).get(key) > 1: | |
raise Exception("NonUniqueKeysException", "Found multiple values for {} in {}".format(key,item)) | |
results.append(return_results(key, item, results_names)) | |
if find_first: | |
return results[0] | |
if len(results) > 1: | |
raise Exception("NonUniqueKeysException", "Found multiple values for {} in {}".format(key,results)) | |
if results: | |
return results[0] | |
else: | |
return None |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment