Find a unique pair (key: value) given by N dictionnaries in python

I would like to find a simple and / or quick way to find the whole common pair (pair: value), given the N dictionnaries in python. (It would be better 3.X)

PROBLEM

Given a set of 3 dicts(but it can be any dict, this is just an example)

n1 = {'a': 1, 'b': 2, 'c': 3}
n2 = {'a': 1, 'b': 4, 'c': 3, 'd': 4}
n3 = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

The result is for general (key: values) for n1, n2and n3 should be:

({'a': 1, 'c': 3})

And for n2and n3it should be

({'a': 1, 'c': 3, 'd': 4})

First I use brute force algorithm that will check every pair (key: value) for each dict

Here is an implementation using a recursive algorithm

SOLUTION A

list_dict = [n1, n2, n3]

def finding_uniquness(ls):

    def recursion(ls, result):
        if not ls:
            return result
        result = {k: v  for k, v in result.items()  for k1, v1 in ls[0].items() if k == k1 and v == v1}
        return recursion(ls[1:], result)

    return recursion(ls[1:], ls[0])


finding_uniquness(list_dict)
# {'c': 3, 'a': 1}

( , , dict, O (N²)?)

, Sets. , ,

B

import functools

list_dict = [n1, n2, n3]
set_list = [set(n.items()) for n in list_dict]

functools.reduce(lambda x, y: x & y, set_list)
 # {('a', 1), ('c', 3)}

, , key list , :

>>> n = {'a': [], 'b': 2, 'c': 3}
>>> set(n.items()) 

TypeError: unhashable type: 'list'

:

  • , A?
  • TypeError B?

, .

+4
3

:

>>> {k: v
     for k, v in list_dict[0].items()
     if all(k in d and d[k] == v
            for d in list_dict[1:])}
{'c': 3, 'a': 1}

list_dict[1:] , all . , , "master":

>>> {k: v
     for k, v in list_dict.pop().items()
     if all(k in d and d[k] == v
            for d in list_dict)}
{'c': 3, 'a': 1}

get , , @Jean-FrançoisFabre:

>>> marker = object()
>>> {k: v
         for k, v in list_dict.pop().items()
         if all(d.get(k, marker) == v
                for d in list_dict)}
{'c': 3, 'a': 1}
+7

, .keys(), , , :

import operator as op
from functools import reduce

common_keys = reduce(op.and_, (d.keys() for d in my_dicts))
common_items = {}
for key in common_keys:
    value = my_dicts[0][key]
    if all(d[key] == value for d in my_dicts):
        common_items[key] = value

, a, , b, .

+3

.

, ; json .

import collections
import itertools
import pickle  

def findCommonPairs(dicts):
    all_pairs = itertools.chain(*[d.items() for d in dicts])
    cnt = collections.Counter(map(pickle.dumps, all_pairs))
    return [pickle.loads(pickled_pair)
            for pickled_pair, count in cnt.items()
            if count == len(dicts)]


>>> findCommonPairs([n1, n2, n3])
[('a', 1), ('c', 3)]

>>> findCommonPairs([{'a': [1,2], 'b': [2,3]}, {'a': [1,2]}])
[('a', [1, 2])]

, . dicts, dicts, , dicts (, ) . , , ( ). , .

+1

Source: https://habr.com/ru/post/1671182/


All Articles