2

I currently have a dictionary d with key: string, and values is another dict.

In the d dictionary values, how can I check which key and values are ALL the same?


Example Dictionary:

zybook, zybooks, zybookz are keys. There can be more than three keys, but I only put two for now. And then the values of d are another dict with {file name : number}

d = {"zybook": 
        {
         "noodle.json": 5,
         "testing.json": 1,
         "none.json": 5
        },
    "zybooks": 
        {
         "noodle.json": 5,
         "ok.json": 1
        },
    "zybookz":
        {
         "noodle.json": 5
        }
    }

Expected Output:

Because {"noodle.json": 5} {"noodle.json": 5} are both the same in zybook, zybooks, and zybookz the output will create another dictionary with all 3 matches.

{"noodle.json": 5}

My attempt:

I honestly don't know how to approach this.

d = {"zybook": { "noodle.json": 5, "testing.json": 1, "none.json": 5},
    "zybooks": {"noodle.json": 5, "ok.json": 1},
    "zybookz": {"noodle.json": 5}
}

for key, value in d.items():
    for k, v in value.items():
        if     
inspiring
  • 123
  • 7
  • 1
    Does `d` only ever have 2 dicts in it? Or more? If more, do you want the elements that are the same between _all_ the dicts, or different outputs for each pair? – Dominic D May 14 '20 at 09:51
  • @DominicD It can have more, I would like the elements that are the same between all dicts. – inspiring May 14 '20 at 09:52
  • @inspiring, What is the expected output for `d = {"zybook": { "noodle.json": 5, "testing.json": 1, "none.json": 5 }, "zybooks": { "noodle.json": 5, "ok.json": 1, "hmm.json": 2, }, "hello": { "wow.json": 7 } }` ? – Mustafa Aydın May 14 '20 at 10:53
  • @MustafaAydın Because it doesn't match all it should return empty. – inspiring May 14 '20 at 10:57
  • Does this answer your question? [Python3 Determine if two dictionaries are equal](https://stackoverflow.com/questions/53348959/python3-determine-if-two-dictionaries-are-equal) – Mike 'Pomax' Kamermans May 14 '20 at 23:28

3 Answers3

2

Try this:

from collections import Counter

res = {z[0]: z[1] for z, count in Counter([(k, v) for x in d for k, v in d[x].items()]).items() if count == len(d)}
deadshot
  • 8,881
  • 4
  • 20
  • 39
2
from functools import reduce
sets = (set(val.items()) for val in d.values())
desired = dict(reduce(set.intersection, sets))
print(desired)
# {'noodle.json': 5}

We first form sets out of the file_name:num pairs of each dictionary. Then, reduce cumulatively looks each set and reduces them to the desired result by taking intersection of those sets. Lastly, converting to a dict as needed.

Mustafa Aydın
  • 17,645
  • 4
  • 15
  • 38
  • Thank you, however the solution does not work if there are multiple files with the same name, but different number. – inspiring May 14 '20 at 10:17
  • @inspiring Can you give an example for that case? I couldn't really get what you meant by "multiple files with same name"? – Mustafa Aydın May 14 '20 at 10:19
  • 1
    @inspiring, Actually that doesn't comply with the concept of dictionaries: if there is more than one item with the same key, then only the last one remains. If you print such a dictionary, you will see that `"noodle.json": 5` is missing because is overridden by `"noodle.json": 1"`. – Mustafa Aydın May 14 '20 at 10:25
  • Oh very true, I completely forgot about that part. Thanks for the help. – inspiring May 14 '20 at 10:26
  • test your output for this `{"zybooks": {"noodle.json": 7, "ok.json": 1}, "zybks": {"noodle.json": 7, "ok.json": 3, "test.json": 7}, "zyks": {"test.json": 7, "ok.json": 1}}` – deadshot May 14 '20 at 10:46
  • @komatiraju032 Gives empty dict as desired? – Mustafa Aydın May 14 '20 at 10:49
  • @MustafaAydın can you explain on what condition it is empty dict – deadshot May 14 '20 at 10:57
  • @komatiraju032, Because there is no `file:num` pair that exists in _all_ of the dictionaries. See OP's comment under the question. – Mustafa Aydın May 14 '20 at 10:59
  • @MustafaAydın I didn't see that one he shouldn't mentioned that in the question – deadshot May 14 '20 at 11:01
  • @komatiraju032 I have updated it, that was my mistake. – inspiring May 14 '20 at 11:02
1

With only the use of embedded Python methods

new = []
for v in d.values():
    new+=list(v.items())
# [('noodle.json', 5), ('testing.json', 1), ('none.json', 5), ('noodle.json', 5), ('ok.json', 1)]

cnt_dict = {v:new.count(v) for v in new}
# {('noodle.json', 5): 3, ('testing.json', 1): 1, ('none.json', 5): 1, ('ok.json', 1): 1}

d2 = {k[0]:k[1] for k,v in cnt_dict.items() if v > 1}
print(d2)
# {'noodle.json': 5}
Laurent B.
  • 1,653
  • 1
  • 7
  • 16