Last active
March 4, 2016 17:34
-
-
Save bplaxco/bed66d1ab7e73cca8097 to your computer and use it in GitHub Desktop.
Quickly runs `func` on elements in dict or list/set/tuple climbing down the nested elements.
This file contains 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
import copy | |
def next(a, i): | |
j = a.index(i) + 1 | |
return a[j] if j < len(a) else None | |
# end next | |
def get_keys(x, default=()): | |
if hasattr(x, 'keys'): | |
return x.keys() | |
elif hasattr(x, '__iter__'): | |
return range(0, len(x)) | |
else: | |
return default | |
# end get_keys | |
def has_key(x, key): | |
if key == None: | |
return False | |
if hasattr(x, 'keys'): | |
return key in x | |
elif hasattr(x, '__iter__'): | |
return key < len(x) | |
# end get_keys | |
def is_pushable(x): | |
return hasattr(x, 'keys') or hasattr(x, '__iter__') | |
# end is_pushable | |
def normalize(obj, func=unicode, functional=True): | |
# Set functional to False to get more speed | |
obj = copy.deepcopy(obj) if functional else obj | |
stack = [] | |
stack_len = stack.__len__ | |
push = stack.append | |
pop = stack.pop | |
keys = get_keys(obj) | |
i = keys and keys[0] | |
start = bool(keys) | |
while start: | |
if has_key(obj, i): | |
el = obj[i] | |
if is_pushable(el): | |
push((obj, keys, next(keys, i))) | |
obj, keys = el, get_keys(el) | |
i = keys[0] | |
else: | |
obj[i] = func(el) | |
i = next(keys, i) | |
else: | |
if stack_len(): | |
obj, keys, i = pop() | |
else: | |
break | |
return obj | |
# normalize |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment