How to compare values of actual key and the previous one?

Question:

I have a dictionary and inside of the values are lists which contain 2 numbers.

For example:

z_n = {'1': [[4, 7], [7, 8], [7, 9], [6, 7]], '2': [[4, 5], [8, 10], [3, 4]]}

First I want to remove the number 7 of all lists inside of the value from the first key.

That works like this:

root = 7

# Iterating through dictionary z_n
for key, value in z_n.items():

    # Iterating through lists of values
    for lis in value:

        #
        if root in lis:

            # Removing 7 from the list
            lis.remove(root)

For the first key it will be like this:

z_n = {'1': [[4], [8], [9], [6]], '2': [[4, 5], [8, 10], [3, 4]]}

From the following keys now on I want to compare their values with the values from the previous key and remove them again from each list.

In this case I want to remove 4, 8, 9 and 6 if they are in '2': [[4, 5], [8, 10], [3, 4]] so that it will be like this:
'2': [[5],[10],[3]].

How is it possible to compare each value of the actual key to all values from the previous key and remove them if they are inside both?

Asked By: maxwell_742

||

Answers:

Picking up from exactly where you are stuck, i.e. I’m assuming you have removed number 7 from your first key in the dictionary.

You can first create a set for all the values for first key, then filter out the values in list of list of values in second key:

values=set(x for v in z_n['1'] for x in v)
z_n['2'] = [[v for v in x if v not in values] for x in z_n['2']]

# z_n
{'1': [[4], [8], [9], [6]], '2': [[5], [10], [3]]}
Answered By: ThePyGuy

This is my solution:

import itertools

def remove_func(sublist, remove_list):
    new_sublist = []
    for i in sublist:
        temp = []
        for j in i:
            if j not in remove_list:
                temp.append(j)
        new_sublist.append(temp)
        
    return new_sublist
    

z_n = {'1': [[4, 7], [7, 8], [7, 9], [6, 7]], '2': [[4, 5], [8, 10], [3, 4]]}

remove_list = [7]
for key, value in z_n.items():
    z_n[key] = remove_func(z_n[key], remove_list )
    remove_list = list(itertools.chain(*z_n[key]))
    
print(z_n)

Output:

{'1': [[4], [8], [9], [6]], '2': [[5], [10], [3]]}
Answered By: Shahab Rahnama

Here’s another approach using sets:

z_n = {'1': [[4, 7], [7, 8], [7, 9], [6, 7]], '2': [[4, 5], [8, 10], [3, 4]]}

root = 7

s = {root}

for i, k in enumerate(z_n.keys()):
    z_n[k] = [list(set(e) - s) for e in z_n[k]]
    if i == 0:
        s = {e[0] for e in z_n[k]}

print(z_n)

Output:

{'1': [[4], [8], [9], [6]], '2': [[5], [10], [3]]}
Answered By: Vlad

Code:

z_n['2'] = [[*(set(sum(z_n['1'], []))^set(val))&set(val),] for idx,val in enumerate(z_n['2'])]

OR

z_n['2'] = [[*set(sum(z_n['1'], [])).intersection(val).symmetric_difference(val),] for idx,val in enumerate(z_n['2'])]

Output:

{'1': [[4], [8], [9], [6]], '2': [[5], [10], [3]]}
Answered By: Stackpy