Last active
February 2, 2018 13:59
-
-
Save u8sand/2ebbaf13b18c15158e19ce6450cfea36 to your computer and use it in GitHub Desktop.
Allows dict access via path list (e.g. path_set(d, [1,2,3], 5) == d[1][2][3]=5)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from util import * | |
from unittest import TestCase | |
class TestUtil(TestCase): | |
def test_path_set(self): | |
self.assertEquals( | |
path_set({}, 'a', 'b'), | |
{'a': 'b'}, | |
'Basic create') | |
self.assertEquals( | |
path_set({'a': {'b': 'c'}}, ['a', 'b'], 'd'), | |
{'a': {'b': 'd'}}, | |
'Replace subpath') | |
self.assertEquals( | |
path_set({'a': {'b': 'c'}}, ['b', 'a'], 'd'), | |
{'a': {'b': 'c'}, 'b': {'a': 'd'}}, | |
'Create subpath') | |
def test_path_get(self): | |
self.assertEquals( | |
path_get({}, ['a', 'b']), | |
None, | |
'Nothing to find') | |
self.assertEquals( | |
path_get({'a': 'b'}, ['a', 'b']), | |
None, | |
'End of the line') | |
self.assertEquals( | |
path_get({'a': 'b'}, 'a'), | |
'b', | |
'Basic find') | |
self.assertEquals( | |
path_get({'a': {'b': 'c'}}, ['a', 'b']), | |
'c', | |
'Find subpath') | |
def test_walk_tree(self): | |
T = { | |
'a': { | |
'b': { | |
'c': 'd' | |
}, | |
'e': { | |
'f': 'g' | |
}, | |
'h': 'i' | |
}, | |
'j': 'k' | |
} | |
V = set([ | |
'a/b/c/d', | |
'a/e/f/g', | |
'a/h/i', | |
'j/k' | |
]) | |
for k, v in walk_tree(T): | |
p = '/'.join(k+[v]) | |
self.assertIn(p, V, "Path found") | |
V.remove(p) | |
self.assertEquals(V, set(), "All paths found") | |
def test_path_merge(self): | |
self.assertEquals( | |
path_merge({}, {'a': 'b'}), | |
{'a': 'b'}, | |
'Simple create') | |
self.assertEquals( | |
path_merge({'a': 'b'}, {}), | |
{'a': 'b'}, | |
'Simple create (reverse)') | |
self.assertEquals( | |
path_merge({'a': 'b'}, {'a': {'b': 'c'}}), | |
{'a': {'b': 'c'}}, | |
'Overlay overwrite') | |
self.assertEquals( | |
path_merge({'a': {'b': 'c'}}, {'a': 'b'}), | |
{'a': 'b'}, | |
'Overlay drop') | |
self.assertEquals( | |
path_merge({'a': {'b': {'c': 'd'}}}, {'a': {'b': {'d': 'e'}}}), | |
{'a': {'b': {'c': 'd', 'd': 'e'}}}, | |
'Overlay merge') |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def path_set(d, k, v): | |
''' Allows dict access via path list (e.g. path_set(d, [1,2,3], 5) == d[1][2][3]=5) ''' | |
d[k[0]] = path_set(d.get(k[0], {}), k[1:], v) if len(k) > 1 else v | |
return d | |
def path_get(d, k, v=None): | |
''' Allows dict access via path list (e.g. path_get(d, [1,2,3]) == d[1][2][3]) ''' | |
if isinstance(d, dict): | |
if len(k) > 1: | |
return path_get(d.get(k[0]), k[1:], v) | |
elif len(k) == 1: | |
return d.get(k[0], v) | |
elif len(k) == 0: | |
return d | |
return v | |
def walk_tree(T, K=[]): | |
''' Allows walking through a tree returning path list and leaf nodes--a bit like os.walk ''' | |
for k,v in T.items(): | |
if type(v) == dict: | |
for item in walk_tree(v, K+[k]): | |
yield item | |
else: | |
yield (K+[k], v) | |
def path_merge(d, *D): | |
''' Like dict(d, **dd for dd in D) but recusively on dicts for internal path merging ''' | |
for DD in D: | |
for k, v in DD.items(): | |
vv = d.get(k, {}) | |
if type(vv) == dict and type(v) == dict: | |
d[k] = path_merge(vv, v) | |
else: | |
d[k] = v | |
return d |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment