Skip to content

Instantly share code, notes, and snippets.

@Jacob-Stevens-Haas
Created June 25, 2020 16:19
Show Gist options
  • Save Jacob-Stevens-Haas/2840aceee43542b475e3c6d73a77f34c to your computer and use it in GitHub Desktop.
Save Jacob-Stevens-Haas/2840aceee43542b475e3c6d73a77f34c to your computer and use it in GitHub Desktop.
Universal Unsafe Unpacker for Python
# import random
def unsafe_unpacker(obj):
"""A generator that traverses an arbitrarily nested iterable of iterables.
Parameters:
obj (iterable): the nested iterables, e.g. a numpy array of lists of tuples
Returns:
A generator whose items are the ordered collection of any non-iterable found
in obj.
Note:
The unsafe bit refers to the possibility that one of the nested iterables
is infinite or contains circular references. Since this is a generator,
it doesn't unpack more than you need, so don't try to fully unpack anything
unsafe.
Also unsafe could refer to excepting RuntimeException as well as StopIteration,
thank you https://www.python.org/dev/peps/pep-0479/.
Diagnostic print lines are commented out, but you can uncomment them to see
the play-by-play.
Example:
```
>>> lolol = [[[1,2],3],[[[4]]]]
>>> for item in unsafe_unpacker(lolol):
>>> print(item)
1
2
3
4
```
"""
if not hasattr(obj, '__iter__'):
yield obj
else:
branch_iterator = obj.__iter__()
curr_leaf = branch_iterator.__next__()
# gen_name = "%08x" % random.getrandbits(32)
# print(f'creating a generator named {gen_name} from ',curr_leaf)
curr_gen = unsafe_unpacker(curr_leaf)
while True:
try:
yield curr_gen.__next__()
except (StopIteration, RuntimeError):
# print(f"{gen_name} excepted!")
curr_leaf = branch_iterator.__next__()
# gen_name = "%08x" % random.getrandbits(32)
# print(f'creating a generator named {gen_name} from ',curr_leaf)
curr_gen = unsafe_unpacker(curr_leaf)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment