Created
October 30, 2020 06:08
-
-
Save nikvdp/e2a87f20680b1b1ecc8084885b15e396 to your computer and use it in GitHub Desktop.
A one liner to unwrap a list (or any iterable) with any amount of nesting
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
""" | |
A handy and cool recursive lambda (!) to safely get an item out of a deeply | |
nested list or iterable: | |
>>> unwrap = lambda x: unwrap(next(iter(x), None)) if '__iter__' in dir(x) and not isinstance(x, str) else x | |
>>> unwrap(2) | |
2 | |
>>> unwrap(["hi"]) | |
'hi' | |
>>> unwrap([[[[[[["ok ok, i get it"]]]]]]]) | |
'ok ok, i get it' | |
see below for how it works | |
""" | |
# as an actual one-liner | |
unwrap = lambda x: unwrap(next(iter(x), None)) if '__iter__' in dir(x) and not isinstance(x, str) else x | |
# formatted over two lines to keep it less than 80 chrs | |
unwrap = lambda x: unwrap(next(iter(x), None)) \ | |
if '__iter__' in dir(x) and not isinstance(x, str) else x | |
# in a more readable form | |
unwrap = ( | |
lambda x: unwrap(next(iter(x), None)) | |
if "__iter__" in dir(x) and not isinstance(x, str) | |
else x | |
) | |
# an shorter but unsafe variant that you can use if you are absolutely sure | |
# that the content does not contain any strings. if it receives a string it | |
# will cause a recursion depth exceeded exception) | |
unwrap = lambda x: unwrap(next(iter(x), None)) if '__iter__' in dir(x) else x | |
""" | |
How it works: | |
It uses `dir()` to check if `x` has an `__iter__()` method. If it does, this | |
means it's iterable, and we can use the `next()` function to ask it to give us | |
the next iteration. The second parameter (`, None`) to `next()` makes `next()` | |
return `None` instead of throwing an exception if there are no more items to | |
iterate over. | |
However, strings behave oddly in python, and have an `__iter__()` method even | |
though they are not actually iterable. So we use `not isinstance(x, str)` to | |
make sure that the item isn't a string. | |
Caveats and limitations: | |
If you're trying to unrwap something that's *actually* iteratable (for | |
example if you tried `unwrap([[[2,3]]])`) you will only get the first | |
result back (2). | |
""" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment