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 ref
erence, 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.