Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter a dictionary according to an arbitrary condition function?

People also ask

How do I filter a dictionary value?

Filter a Dictionary by values in Python using filter() filter() function iterates above all the elements in passed dict and filter elements based on condition passed as callback.

How do I filter a dictionary list in Python?

We can easily search a list of dictionaries for an item by using the filter() function with a lambda function. In Python3, the filter() function returns an object of the filter class. We can convert that object into a list with the list() function.

Can a dictionary have arbitrary data types in Python?

Dictionary values have no restrictions. They can be any arbitrary Python object, either standard objects or user- defined objects. However, same is not true for the keys.

Can dictionaries contain objects of arbitrary type?

Dictionaries can contain objects of arbitrary type, even other containers such as lists and nested dictionaries.


You can use a dict comprehension:

{k: v for k, v in points.items() if v[0] < 5 and v[1] < 5}

And in Python 2, starting from 2.7:

{k: v for k, v in points.iteritems() if v[0] < 5 and v[1] < 5}

dict((k, v) for k, v in points.items() if all(x < 5 for x in v))

You could choose to call .iteritems() instead of .items() if you're in Python 2 and points may have a lot of entries.

all(x < 5 for x in v) may be overkill if you know for sure each point will always be 2D only (in that case you might express the same constraint with an and) but it will work fine;-).


points_small = dict(filter(lambda (a,(b,c)): b<5 and c < 5, points.items()))

>>> points = {'a': (3, 4), 'c': (5, 5), 'b': (1, 2), 'd': (3, 3)}
>>> dict(filter(lambda x: (x[1][0], x[1][1]) < (5, 5), points.items()))

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

dict((k, v) for (k, v) in points.iteritems() if v[0] < 5 and v[1] < 5)

I think that Alex Martelli's answer is definitely the most elegant way to do this, but just wanted to add a way to satisfy your want for a super awesome dictionary.filter(f) method in a Pythonic sort of way:

class FilterDict(dict):
    def __init__(self, input_dict):
        for key, value in input_dict.iteritems():
            self[key] = value
    def filter(self, criteria):
        for key, value in self.items():
            if (criteria(value)):
                self.pop(key)

my_dict = FilterDict( {'a':(3,4), 'b':(1,2), 'c':(5,5), 'd':(3,3)} )
my_dict.filter(lambda x: x[0] < 5 and x[1] < 5)

Basically we create a class that inherits from dict, but adds the filter method. We do need to use .items() for the the filtering, since using .iteritems() while destructively iterating will raise exception.


dict((k, v) for (k, v) in points.iteritems() if v[0] < 5 and v[1] < 5)