I have a list of python dictionaries (let's assume each dict is flat for the time being). The keys are all strings and the values are strings or real numbers. I would like the user to have the freedom to filter this dict in which ever way they choose to, using some kind of query language. The query can contain nested 'and's and/or 'or's.
What would be the best way to implement (or preferably re-use) a language/sytax which I can execute safely inside the application (an unsafe option would be to use eval)?
for eg:
list_of_dicts = [
{"type":"a", "val1": 10, "val2": 12.2, "val3": "off"},
{"type":"b", "val1": 230, "val2": 15.5, "val3": "on"},
{"type":"c", "val1": 40, "val3": "off"},
{"type":"a", "val1": 60, "val2": 52.0, "val4": 12},
{"type":"c", "val1": 80, "val2": 18.1},
]
The user should be able to say:
"Give me all items where type is a or b. From the resulting list, give me all cases where val3 is off"
Which translates to:
cond = lambda x: x.get("type") in ["a", "b"] and x.get("val3") == "off"
resultant = [a for a in list_of_dicts if cond(a)]
# Out: [{'type': 'a', 'val1': 10, 'val2': 12.2, 'val3': 'off'}]
CodePudding user response:
Use Pandas and query method. Python is an expressive language so why don't use this.
import pandas as pd
df = pd.DataFrame(list_of_dicts)
out = df.query("""type.isin(['a', 'b']) and val3 == 'off'""")
print(out)
# Output
type val1 val2 val3 val4
0 a 10 12.2 off NaN
