1

I'm trying to search through a big python dictionary for items that have these parameters ->

"df" between 3 and 4

"ar" between 6 and 9

"od" between 1 and 2

The json string looks something like this

values = { "key1" : { "ar" : 8, "df" : 3, "od" : 1, "id" : 1} , 
           "key2" : { "ar" : 5, "df" : 3, "od" : 5, "id" : 2},
           "key3" : { "ar" : 6, "df" : 4, "od" : 2, "id" : 3}}

I want to get only the values from the ones that meet my condition (key1 and 3), but I also don't want to make a whole lines of codes for each combination possible (in case I just want to search for "od" and "df" or only "ar"). I managed to search through only value as the example below

ar_range_min = 6
ar_range_max = 9
df_range_min = 3
df_range_min = 4
myDict = { "key1" : { "ar" : 8, "df" : 3, "od" : 1, "id" : 1} , 
           "key2" : { "ar" : 5, "df" : 3, "od" : 5, "id" : 2},
           "key3" : { "ar" : 6, "df" : 4, "od" : 2, "id" : 3}}

def df_search(df_min, df_max):
    global values, df_range
    listOfDicts = []
    foreach k in myDict:
        z = z+1
        if df_min <= k["df"] >= df_max:
            listOfDicts.append(k)  
    return listOfDicts

def ar_search(ar_min, ar_max):
    global values
    listOfDicts = []
    foreach k in myDict:
        z = z+1
        if ar_min <= k["ar"] >= ar_max:
            listOfDicts.append(k)  
    return listOfDicts

match_df = df_search(df_range_min, df_range_max)
match_ar = ar_search(ar_range_min, ar_range_max)
match_both = ???

What I don't know is how to create a new dictionary with the values in common between match_df and match_ar and how to merge them if I have 3 dictionaries (parameters)

PS: This I not the actual dict, it has more nested keys in each Children

SeoFernando
  • 61
  • 2
  • 13
  • Please simplify your code and go step by step. First make sure your function is giving desired output. what is `x` in your `df_search`. – Rahul Jan 16 '18 at 04:04

2 Answers2

0

You can first merge both arrays (correct me if i'm wrong on the syntax)

match_both = match_df.extend(match_ar)

And then you should eliminate duplicates

match_both = list(set(match_both))

I could be very very wrong, please correct me if I misunderstood the question

I used as reference:
What is the syntax to insert one list into another list in python?
Removing duplicates in lists

Uriel Chami
  • 418
  • 3
  • 13
0

Just to make sure we're on the same page, my understanding is that this is what you want. In the above example, df_search() returns key1, key2, and key3 since they all have df in range [3,4] and ar_search() returns key1 and key3 because they have ar in the appropriate range. What you want "match_both" to be equal to is key1 and key3 since those are the 2 keys that are present in both the ar and df search.

In order to accomplish this I would recommend you re-organize your code in the following way: create a generic function that takes in the dictionary, a string ( "ar", "df", etc) and also a range ([3,4], [6,7,8,9], etc) and returns a list of all the keys in the dictionary that match the condition. For example:

def getMatchingKeys(values, s, matchRange):
    matchingKeys = []
    for key in values:
        if values[key][s] in matchRange:
        matchingKeys.append(key)
    return matchingKeys

Now, with this function, we can dynamically get all the keys that match and accomplish what you were doing with the two separate search functions:

match_df = getMatchingKeys(values, "df", [3,4])  # returns ["key1", "key2", "key3"]
match_ar = getMatchingKeys(values, "ar", [6,7,8,9])  # returns ["key1", "key3"]

Now, all we need to do is find the keys that are contained in both match_df and match_ar. To do this we can turn the lists into sets and get the intersection of the two (all keys contained in both):

match_both = set(match_df) & set(match_ar)

Now, if you want to add the restriction of "or" in [1,2], you can do that easily:

match_df = getMatchingKeys(values, "df", [3,4])  # returns 
match_ar = getMatchingKeys(values, "ar", [6,7,8,9])
match_od = getMatchingKeys(values, "od", [1,2])
match_all = set(match_df) & set(match_ar) & set(match_od)

However, it is probably better to create a function that takes in a list of constraints and programmatically gets all keys that match all constraints:

def getKeysMatchingConstraints(values, constraints):
    keys = None
    for (s, matchRange) in constraints:
       result = getMatchingKeys(values, s, matchRange)
       if keys == None: keys = set(result)
       else: keys = keys & set(result)
    return keys

getKetsMatchingConstraints(values, [("df", [3,4]), ("ar", [6,7,8,9]), ("od", [1,2])])
Rohan Varma
  • 1,145
  • 6
  • 11