0

I have a function for filtering a list of dict based on the value of certain keys, like a SELECT * WHERE xxx query in SQL

list_of_dict = [
{'key1':val, 'key2':val},
{'key1':val, 'key2':val},
...
]

def filter_list(list_of_dict, key1, key2=None):
    if key2:
         filtered_list = [i for i in list_of_dict if i['key1']==key1 and i['key2']==key2]
    else:
         filtered_list = [i for i in list_of_dict if i['key1']==key1]

but when I have more keys as arguments to the function the if ...else... could go really long.

Is there a more pythonic way to do this?

1 Answer 1

4

If you have a large or variable number of keys, you can use all to loop over them. Here's an example where the key values are provided as keyword arguments:

def filter_dicts(dicts, **keys):
    return [
        d for d in dicts
        if all(d[k] == v for k, v in keys.items())
    ]

As @juanpa.arrivillaga points out, dict_items objects behave like sets in many regards, so you can alternatively filter for dictionaries which have keys as a subset:

def filter_dicts(dicts, **keys):
    return [d for d in dicts if keys.items() <= d.items()]

Example:

>>> dicts = [{'x': 1, 'y': 2}, {'x': 1, 'y': 3}]
>>> filter_dicts(dicts, x=1)
[{'x': 1, 'y': 2}, {'x': 1, 'y': 3}]
>>> filter_dicts(dicts, x=1, y=2)
[{'x': 1, 'y': 2}]
>>> filter_dicts(dicts, y=3)
[{'x': 1, 'y': 3}]
Sign up to request clarification or add additional context in comments.

3 Comments

consider: if keys.items() <= d.items()
@juanpa.arrivillaga I did not know you could use a dict_items object in that way; if you post it as an answer I will upvote.
Eh, the crux of the answer is in using **kwargs. You can just add it as an alternative. I'm trying to up the awareness of dict view objects as set-like objects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.