Home > Software engineering >  Matching a Reference Dict to a List of Dicts
Matching a Reference Dict to a List of Dicts

Time:10-01

So I have a reference dict

ref = {"a": 1, "b": 2}

and a list of dicts

dict_list = [{"a": 1, "b": 2, "c": "success!"}, {"a": 1, "b": 3, "c": "nope!"}]

What I want is to find the dict in dict_list which matches the reference, and returns the value c (i.e. "success!"). I was able to do this, but I'm not a fan of this solution at all:

In [7]: import pandas as pd
   ...: def f(ref, dict_list):
   ...:     df = pd.DataFrame.from_records(dict_list)
   ...:     return df.loc[(df["a"] == ref["a"]) & (df["b"] == ref["b"])].c[0]
   ...: 
   ...: f(ref, dict_list)
Out[7]: 'success!'

if anyone has anything more elegant (ideally in pure python) would be great!

CodePudding user response:

Use next:

>>> next((x['c'] for x in dict_list if ref.items() < x.items()))
'success!'
>>> 

Or:

>>> next((x['c'] for x in dict_list if dict(x, **ref) == x))
'success!'
>>> 

This will get the key c when the ref dictionary is a subset of the iterator dictionaries. This won't only work for a and b keys, it works for all cases.

In Python 3, to check if a dictionary is a subset of another, you can use the < operator.

For the second case, since dictionaries can't have additional keys, it joins the two dictionaries and determines whether it's the same as the original dictionary iterator, if so, it yields the c key from iterator x.

Edit:

As @sj95126 mentioned, as of Python 3.9 you could use the concatenation method:

>>> next((x['c'] for x in dict_list if x | ref == x))
'success!'
>>> 

This is the same logic as dict(x, **ref).

Edit 2:


Obviously, you could do:

>>> next((x['c'] for x in dict_list if [x['a'], x['b']] == list(ref.values())))
'success!'
>>> 

For only a and b keys.

  • Related