From 3e934e245b1294b88102deebea2ff06caae77640 Mon Sep 17 00:00:00 2001 From: Fabio Caccamo Date: Tue, 2 Jul 2019 15:15:31 +0200 Subject: [PATCH] Added filter utility method. --- README.md | 7 +++++++ README.rst | 7 +++++++ benedict/dicts/__init__.py | 4 ++++ benedict/dicts/utility.py | 11 +++++++++++ tests/test_utility_dict.py | 19 +++++++++++++++++++ 5 files changed, 48 insertions(+) diff --git a/README.md b/README.md index df75bf7..b61331d 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,13 @@ s = d.dump_items(key=None) print(s) ``` +```python +# Return a filtered dict using the given predicate function. +# Predicate function receives key, value arguments and should return a bool value. +predicate = lambda k, v: v is not None +d.filter(predicate) +``` + ```python # Get value by key or keypath trying to return it as bool. # Values like `1`, `true`, `yes`, `on`, `ok` will be returned as `True`. diff --git a/README.rst b/README.rst index be965d1..e86454d 100644 --- a/README.rst +++ b/README.rst @@ -75,6 +75,13 @@ API s = d.dump_items(key=None) print(s) +.. code:: python + + # Return a filtered dict using the given predicate function. + # Predicate function receives key, value arguments and should return a bool value. + predicate = lambda k, v: v is not None + d.filter(predicate) + .. code:: python # Get value by key or keypath trying to return it as bool. diff --git a/benedict/dicts/__init__.py b/benedict/dicts/__init__.py index 406effd..bb37751 100644 --- a/benedict/dicts/__init__.py +++ b/benedict/dicts/__init__.py @@ -26,6 +26,10 @@ class benedict(KeypathDict, ParseDict, UtilityDict): def deepcopy(self): return super(benedict, self).deepcopy() + @benediction + def filter(self, func): + return super(benedict, self).filter(func) + @classmethod @benediction def fromkeys(cls, sequence, value=None): diff --git a/benedict/dicts/utility.py b/benedict/dicts/utility.py index 015efa9..3186219 100644 --- a/benedict/dicts/utility.py +++ b/benedict/dicts/utility.py @@ -43,3 +43,14 @@ class UtilityDict(dict): def dump_items(self, key=None): return self.dump(self.get(key) if key else self) + def filter(self, predicate): + if not callable(predicate): + raise ValueError('predicate argument must be a callable.') + d = {} + keys = self.keys() + for key in keys: + val = self.get(key, None) + if predicate(key, val): + d[key] = val + return d + diff --git a/tests/test_utility_dict.py b/tests/test_utility_dict.py index 95fcf94..685341f 100644 --- a/tests/test_utility_dict.py +++ b/tests/test_utility_dict.py @@ -154,3 +154,22 @@ class UtilityDictTestCase(unittest.TestCase): output = b.dump_items() self.assertEqual(output, expected_output) + def test_filter(self): + d = { + 'a': 1, + 'b': 2, + 'c': '4', + 'e': '5', + 'f': 6, + 'g': 7, + } + b = UtilityDict(d) + f = b.filter(lambda key, val: isinstance(val, int)) + r = { + 'a': 1, + 'b': 2, + 'f': 6, + 'g': 7, + } + self.assertEqual(f, r) +