Suppose obj
has an __iter__()
method.
We want to write a function which accepts obj
as input and outputs a nested list of lists of lists .... of lists of strings.
If an object is iterable, and is not a string, we recur.
If an object is a string, we return the string.
If an object is non-iterable, we call the string-class constructor on that object, and return the resulting string.
Unfortunately, there may be self-loops. That is, an objects iter method might return an object we have seen previously.
root.__iter__().__next__().__next__().__iter__().__next__().__next__().__iter__().__next__() == root
Maybe we should use the id()
function to check if the object has been seen previously?
CodePudding user response:
Try this:
from collections.abc import Iterable
def collect(obj):
if isinstance(obj, Iterable) and not isinstance(obj, str):
return list(map(collect, obj))
else:
return str(obj)
obj = iter([iter([iter(['a', 2]), 'cd']), iter(['ef', 'gh'])])
print(collect(obj)) # => [[['a', '2'], 'cd'], ['ef', 'gh']]
I think that the id()
check is necessary because once an iterator is iterated through, all the elements will be exhausted and there won't be anything else to iterate through.
CodePudding user response:
This approach optimistically iterates any non-string t
and recovers from errors using an exception handler -
def collect(t):
try:
if isinstance(t, str):
return t
else:
return list(collect(v) for v in t)
except TypeError:
return t