From d46f683e7695e0193d2ab93692cd1c72f74aceac Mon Sep 17 00:00:00 2001 From: Russell Ballestrini Date: Mon, 25 Sep 2017 11:19:18 -0700 Subject: [PATCH] wild mode: case insesitive key substring nested_lookups --- .gitignore | 1 + README.rst | 32 ++++++++++++++++++++++++++++++++ nested_lookup/nested_lookup.py | 14 +++++++------- setup.py | 2 +- test_nested_loopkup.py | 18 +++++++++++++++++- 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 1665159..0cb92e2 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ __pycache__* build/* dist/* nested_lookup.egg-info/* +.cache/ diff --git a/README.rst b/README.rst index 8d6aab1..5bae3a3 100644 --- a/README.rst +++ b/README.rst @@ -45,6 +45,38 @@ tutorial >>> print(nested_lookup('taco', document)) [42, 69] + +wild +======== + +We also have a `wild` mode that treats the given `key` as a case insensitive +substring of all the keys in the document and returns any values which match. + +For example: + +.. code-block:: python + + from nested_lookup import nested_lookup + + my_document = { + 'name' : 'Russell Ballestrini', + 'email_address' : 'test1@example.com', + 'other' : { + 'secondary_email' : 'test2@example.com', + 'EMAIL_RECOVERY' : 'test3@example.com', + }, + }, + + results = nested_lookup( + key = 'mail', + document = my_document + wild = True, + ) + + print(results) + ['test1@example.com', 'test2@example.com', 'test3@example.com'] + + misc ======== diff --git a/nested_lookup/nested_lookup.py b/nested_lookup/nested_lookup.py index 31d21d6..d5a7226 100644 --- a/nested_lookup/nested_lookup.py +++ b/nested_lookup/nested_lookup.py @@ -1,25 +1,25 @@ from six import iteritems -def nested_lookup(key, document): +def nested_lookup(key, document, wild=False): """Lookup a key in a nested document, return a list of values""" - return list(_nested_lookup(key, document)) + return list(_nested_lookup(key, document, wild=wild)) -def _nested_lookup(key, document): +def _nested_lookup(key, document, wild=False): """Lookup a key in a nested document, yield a value""" if isinstance(document, list): for d in document: - for result in _nested_lookup(key, d): + for result in _nested_lookup(key, d, wild=wild): yield result if isinstance(document, dict): for k, v in iteritems(document): - if k == key: + if key == k or (wild and key.lower() in k.lower()): yield v elif isinstance(v, dict): - for result in _nested_lookup(key, v): + for result in _nested_lookup(key, v, wild=wild): yield result elif isinstance(v, list): for d in v: - for result in _nested_lookup(key, d): + for result in _nested_lookup(key, d, wild=wild): yield result diff --git a/setup.py b/setup.py index d5daf48..a9a061d 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ with open('requirements.txt', 'r') as f: setup( name = 'nested-lookup', - version = '0.1.3', + version = '0.1.4', description = 'lookup a key in a deeply nested document of dicts and lists', keywords = 'nested document dictionary dict list lookup schema json xml yaml', long_description = open('README.rst').read(), diff --git a/test_nested_loopkup.py b/test_nested_loopkup.py index d9b9d4e..5a2af8d 100644 --- a/test_nested_loopkup.py +++ b/test_nested_loopkup.py @@ -35,4 +35,20 @@ class TestNestedLookup(TestCase): self.assertIn(200, results) self.assertSetEqual({100,200}, set(results)) - + def test_wild_nested_lookup(self): + results = nested_lookup( + key = 'mail', + document = { + 'name' : 'Russell Ballestrini', + 'email_address' : 'test1@example.com', + 'other' : { + 'secondary_email' : 'test2@example.com', + 'EMAIL_RECOVERY' : 'test3@example.com', + }, + }, + wild = True, + ) + self.assertEqual(3, len(results)) + self.assertIn('test1@example.com', results) + self.assertIn('test2@example.com', results) + self.assertIn('test3@example.com', results)