简体   繁体   中英

Comparing and matching values in a dictionary by getting its values from a nested dictionary taking reference from another dictionary

I'm new to Python and I'm trying to work on a problem but don't know how to proceed. Sorry if there are any mistakes. You can ask me if my question is not clear. Even a small idea as to how to proceed would be helpful.

I have a nested dictionary as-

dicti = {0: {'Living': ['Tiger', 'Lion'],
             'NonLiving': ['Table', 'Anything']},
         1: {'Living': ['Dog', 'Animal'],
             'NonLiving': ['Cup', 'Chair']},
         2: {'Living': ['Crow', 'Pig'],
             'NonLiving': ['Home', 'Desk']},
         3: {'Living': ['Tiger', 'Lion'],
             'NonLiving': ['Cup', 'Stationery']},
         4: {'Living': ['Lion', 'Hen'],
             'NonLiving': ['Eraser', 'Pen']},
         5: {'Living': ['Animal', 'Bird'],
             'NonLiving': ['Anything', 'Anything']},
         6: {'Living': ['Bird', 'Shark'],
             'NonLiving': ['Desk', 'Table']},
         7: {'Living': ['Tiger', 'Fish'],
             'NonLiving': ['Book', 'Stationery']},
         8: {'Living': ['Crow', 'Pig'],
             'NonLiving': ['Home', 'Table']},
         9: {'Living': ['Anything', 'Animal'],
             'NonLiving': ['Stationery', 'Eraser']},
         10: {'Living': ['Fish', 'Anything'],
             'NonLiving': ['Book', 'Chair']},
         11: {'Living': ['Wolf', 'Dog'],
             'NonLiving': ['Desk', 'Table']},
         12: {'Living': ['Shark', 'Crow'],
             'NonLiving': ['Chair', 'Home']}}

I have a dictionary with labels for all the items as-

Labels = {'Tiger': '001',
          'Pig': '002',
          'Lion': '003',
          'Dog': '004',
          'Wolf': '004',
          'Crow': '201',
          'Hen': '203',
          'Shark': '408',
          'Whale': '405',
          'Desk': '610',
          'Table': '610',
          'Chair': '719',
          'Pen': '817',
          'Book': '880',
          'Eraser': '815',
          'Tape': '525'}

Note that- Dog, Wolf and Desk, Table have same label numbers.

The items are grouped in another dictionary as-

Groups = {'Fish': ['Shark', 'Whale'],
          'Bird': ['Crow', 'Hen'],
          'Animal': ['Tiger', 'Pig', 'Lion', 'Dog', 'Wolf'],
          'Home': ['Desk', 'Chair', 'Table'],
          'Stationery': ['Pen', 'Book', 'Eraser', 'Tape']}

Note that- The group names represent labels of all items within the group. ie 'Fish' will have labels 408,405. Similarly, 'Animal' will have labels 001,002,003,004

I have another dictionary which is given where I want to compare the items from the dicti dictionary-

Compare= {'Alpha': [[0, 1], [0, 3], [3, 4], [1, 2], [6, 12], [4, 5]],
          'Beta': [[4, 6], [3, 4], [1, 5], [6, 10], [10, 12], [2, 8]],
          'Gamma': [[0, 8], [7, 9], [3, 5], [1, 11], [1, 6], [1, 7], [5, 7]]}

The numbers 0,1,2,3...,12 in "Compare" are the keys in dicti dictionary. I want to compare the pairs as [0,1] where 0 is compared to 1; [0,3] where 0 is compared to 3 and so on for all the items in Compare. The comparison is to be done one by one first for the first elements of list 'Living' by its value in labels , then for second elements of list 'Living'. If Living matches then move on to the First elements of list NonLiving followed by Second elements of list NonLiving. Every time there is not a match in any part, that pair needs to be removed from the list in "Compare". For example: At first while comparing the first elements in Living in Compare, the output should be-

Compare = {'Alpha': [[0, 3], [4, 5]],
           'Beta': [[1, 5], [10, 12], [2, 8]],
           'Gamma': [[3, 5], [1, 11], [5, 7]]}

Note that- [4,5] is kept in Alpha and not removed as the first elements in living for these two keys are 'Lion' and 'Animal'; Lion falls under the category 'Animal' in 'Groups' dictionary. [1,5], [10,12] remains in Beta following the same logic. [1,11] is kept in Gamma as the value of Dog and Wolf in 'Labels' dictionary is same.

Now for the second iteration, while comparing the second elements in Living, it has to be done from this new Compare. The output should be-

Compare = {'Alpha': [[0, 3], [4, 5]],
           'Beta': [[10, 12], [2, 8]],
           'Gamma': [[1, 11]]}

Note that- [10,12] in Beta is kept and not removed as their second elements in Living are 'Anything' and 'Crow'. The value 'Anything' represents all the labels. So it will always be a match irrespective of the comparison.

Similarly from among the items in new Compare dictionary, we compare the first elements of 'NonLiving'. And remove the pairs that do not match. And again form a new Compare dictionary by updating it. At last we compare the second elements of the 'NonLiving' key. The final output should be-

Compare = {'Alpha': [[4, 5]],
           'Beta': [[2, 8]],
           'Gamma': ''}

You can use filter with a custom filter function:

dicti = {0: {'Living': ['Tiger', 'Lion'], 'NonLiving': ['Table', 'Anything']}, 1: {'Living': ['Dog', 'Animal'], 'NonLiving': ['Cup', 'Chair']}, 2: {'Living': ['Crow', 'Pig'], 'NonLiving': ['Home', 'Desk']}, 3: {'Living': ['Tiger', 'Lion'], 'NonLiving': ['Cup', 'Stationery']}, 4: {'Living': ['Lion', 'Hen'], 'NonLiving': ['Eraser', 'Pen']}, 5: {'Living': ['Animal', 'Bird'], 'NonLiving': ['Anything', 'Anything']}, 6: {'Living': ['Bird', 'Shark'], 'NonLiving': ['Desk', 'Table']}, 7: {'Living': ['Tiger', 'Fish'], 'NonLiving': ['Book', 'Stationery']}, 8: {'Living': ['Crow', 'Pig'], 'NonLiving': ['Home', 'Table']}, 9: {'Living': ['Anything', 'Animal'], 'NonLiving': ['Stationery', 'Eraser']}, 10: {'Living': ['Fish', 'Anything'], 'NonLiving': ['Book', 'Chair']}, 11: {'Living': ['Wolf', 'Dog'], 'NonLiving': ['Desk', 'Table']}, 12: {'Living': ['Shark', 'Crow'], 'NonLiving': ['Chair', 'Home']}}
Labels = {'Tiger': '001', 'Pig': '002', 'Lion': '003', 'Dog': '004', 'Wolf': '004', 'Crow': '201', 'Hen': '203', 'Shark': '408', 'Whale': '405', 'Desk': '610', 'Table': '610', 'Chair': '719', 'Pen': '817', 'Book': '880', 'Eraser': '815', 'Tape': '525'}
Groups = {'Fish': ['Shark', 'Whale'], 'Bird': ['Crow', 'Hen'], 'Animal': ['Tiger', 'Pig', 'Lion', 'Dog', 'Wolf'], 'Home': ['Desk', 'Chair', 'Table'], 'Stationery': ['Pen', 'Book', 'Eraser', 'Tape']}
Compare = {'Alpha': [[0, 1], [0, 3], [3, 4], [1, 2], [6, 12], [4, 5]], 'Beta': [[4, 6], [3, 4], [1, 5], [6, 10], [10, 12], [2, 8]], 'Gamma': [[0, 8], [7, 9], [3, 5], [1, 11], [1, 6], [1, 7], [5, 7]]}
def comp(a, b):
   if 'Anything' in [a, b]:
      return True
   return ({Labels[a]} if a in Labels else {Labels.get(i, i) for i in Groups.get(a, [])})\
          &({Labels[b]} if b in Labels else {Labels.get(i, i) for i in Groups.get(b, [])})

def valid_pair(pair):
   [l1, l2], [l3, l4] = dicti[pair[0]]['Living'], dicti[pair[-1]]['Living']
   if not comp(l1, l3) or not comp(l2, l4):
      return False
   [nl1, nl2], [nl3, nl4] = dicti[pair[0]]['NonLiving'], dicti[pair[-1]]['NonLiving']
   return comp(nl1, nl3) and comp(nl2, nl4)

r = {a:k if (k:=[*filter(valid_pair, b)]) else '' for a, b in Compare.items()}

Output:

{'Alpha': [[4, 5]], 'Beta': [[2, 8]], 'Gamma': ''}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM