-1

I have a dictionary d = { a:{d:val1, e:val2, f:null}, b:{p:val3, q:val4, r:val5 }}

So I want to take value of each key and compare the nested key values between themselves and a new dictionary need to be formed as new_dict={a:{equal: [d,e],unequal:[], null:f}, b:{equal:[p,q], unequal:r, null:[]}}

which indicates a's corresponding value {d:val1, e:val2, f:null} with nested values val1, val2, null got compared among themselves got re-structured as a:{equal: [d,e], null:f} if d,e values val1=val2 and f is a null value and so every key is expected to have have the value similar to this format {a:{equal: [], unequal:[], null:[]}}.

TR007
  • 47
  • 1
  • 8
  • Your question isn't very clear. For example, what happens if two entries have the same value, but then two other entries have the same value, but a different one? Perhaps you can provide an example that shows what you want to achieve? Also, why do you want this - perhaps a better way of doing what you want is available? – Grismar Jun 17 '19 at 04:02
  • So in the example above, let's say we iterate over the dictionary items, so for the first iteration the key is 'a' and value is '{d:val1, e:val2, f:null}' so I only want to process and compare the nested values between each other under a which are val1, val2, null and categorize them into 3 categories which are equal, unequal and null which leads me to this example structure {a:{equal: [], unequal:[], null:[]}} and same goes on with 'b'. I want to organize the data in this way as this is the best way to categorize as per what I need. – TR007 Jun 17 '19 at 04:11
  • You're not addressing my question though. Your python code isn't valid, since your keys aren't in quotes, but apart from that, how would you expect this to be interpreted: `{ 'a': { 'd': 'val1', 'e': 'val1', 'f': 'val2', 'g': 'val2' }}` - clearly `d` equals `e` and `f` equals `g`, but they don't equal each other, so you likely don't want all of them in one pile? – Grismar Jun 17 '19 at 04:26
  • Sorry for the misunderstanding. I should have put numbers in there. When I say "val" it means an floating integer something like ```{ 'a': { 'd': '20.1', 'e': '20.1', 'f': '20.2', 'g': 'null' }}```restructured to ```{ 'a': { 'equals': ['d','e'], 'unequals': ['f]', 'null': ['g']}}``` – TR007 Jun 17 '19 at 04:40
  • And what about `{ 'a': { 'd': '20.1', 'e': '20.1', 'f': '20.2', 'g': '20.2' }}`? What does that end up as? – Grismar Jun 17 '19 at 04:42
  • Like this ```{ 'a': { 'equals': ['d','e'], 'unequals': ['f]', 'null': ['g']}}``` – TR007 Jun 17 '19 at 04:43
  • Did you look closely at what I'm asking? Why would you expect `'null': ['g']`? My example has `'g': '20.2'`? – Grismar Jun 17 '19 at 04:46
  • { 'a': { 'd': '20.1', 'e': '20.1', 'f': '20.2', 'g': '20.2' }} this will end up as { 'a': { 'equals': ['d','e'], 'unequals': ['f', 'g'], 'null': ['']}} taking d's value as reference for comparison. Sorry I did not look at it close enough. – TR007 Jun 17 '19 at 05:21
  • And `{ 'a': { 'd': '20.1', 'e': '20.1', 'f': '20.2', 'g': '20.2', 'h': '20.3', 'i': '20.3' }}`? Always take the first value in the dictionary as the reference, so `{ 'a': { 'equals': ['d','e'], 'unequals': ['f', 'g', 'h', 'i'], 'null': ['']}}`? Because this is assuming that a dictionary guarantees order (which it doesn't, unless you assume Python >= 3.7.0). – Grismar Jun 17 '19 at 05:25

1 Answers1

0

You can use it, a little long but with clear and simple explained passages, there are thousands different ways of doing it anyway and a lot of "more elegant" ones:

### dictionary in your example
d = { "a":{"d":"val1", "e":"val2", "f":"null"}, "b":{"p":"val3", "q":"val4", "r":"val5" }}
### new dictionary to fill with the results
compared = {}

### open loop on key, value elementd of your dict
for k, v in d.items() :
    ### open a new dict to store the equals, unequals, nulls
    subcompared = {}
    ### open the lists to store the elements
    equals = []; unequals = []; nulls = [];
    ### open loop on k,v items of the subdictionary in your dict
    for sub_k, sub_v in v.items() :
        ### take the first 3 letters of the value (assuming your comparison what kind of it) 
        sub_v_start = sub_v[0:2]
        ### IF null put in list and skip to next iteration 
        if sub_v == "null" :
            nulls.append( sub_k )
            continue
        ### open another loop on the subdictionaries of the dict
        for sub_k2, sub_v2 in v.items() :
            ### if same value of the outer loop skip to net iteration
            if sub_k2 == sub_k or sub_v2 == "null" :
                continue
            else :
                ### if same first 3 letters of the subvalue
                if sub_v2.startswith(sub_v_start) :
                    ### if not in list put the keys in list (a simple way to avoid suplication, you could also use SET after etc.)
                    if sub_k not in equals :
                        equals.append( sub_k )
                    if sub_k2 not in equals :
                        equals.append( sub_k2 )
                ### if first 3 letters differents the same for unequals
                else :
                    if sub_k not in unequals :
                        unequals.append( sub_k )
                    if sub_k2 not in unequals :
                        unequals.append( sub_k2 )
    ### put the lists as values for the relative keys of the subdictionary renewed at every outest loop
    subcompared["equals"] = equals
    subcompared["unequals"] = unequals
    subcompared["nulls"] = nulls
    ### put the subdictionary as value for the same KEY value of the outest loop in the compared dict
    compared[k] = subcompared

### print results
compared
{'b': {'unequals': [], 'equals': ['q', 'r', 'p'], 'nulls': []}, 'a': {'unequals': [], 'equals': ['e', 'd'], 'nulls': ['f']}}

if you want the keys of the new dict ordered in a specific way you can use OrderedDict for example

cccnrc
  • 1,195
  • 11
  • 27