问题
Assume I have the following input:
items = [1, 2, [3, 4], (5, 6), 'ciao', range(3), (i for i in range(3, 6))]
and I want to perform some recursive operation on items
.
For the sake of simplicity, let's say I want to flatten items (but could be anything else), one way of doing this would be:
def flatten(items, max_depth=-1, shallow=(str, bytes, bytearray)):
for item in items:
if shallow and isinstance(item, shallow) or max_depth == 0:
yield item
else:
try:
for subitem in flatten(item, max_depth - 1, shallow):
yield subitem
except TypeError:
yield item
this would produce:
print(list(flatten(items)))
[1, 2, 3, 4, 5, 6, 'ciao', 0, 1, 2, 3, 4, 5]
Now how could I modify flatten()
so that I could produce the following (for arbitrary nesting levels)?
print(list(flatten(items, shallow=None)))
[1, 2, 3, 4, 5, 6, 'c', 'i', 'a', 'o', 0, 1, 2, 3, 4, 5]
Other inputs to be supported:
items = [['best', 'func'], 'ever']
print(list(flatten(items, shallow=None)))
# ['b', 'e', 's', 't', 'f', 'u', 'n', 'c', 'e', 'v', 'e', 'r']
Note: I am looking for an approach that does not rely on explicitly checking for str
, bytes
or bytearray
as this is quite brittle, should it appear another type which has the property that iterating through it yields the item itself.
This is related to the following: Control recursion on nested lists / strings
回答1:
If you change
if shallow and isinstance(item, shallow) or max_depth == 0:
to
if shallow and isinstance(item, shallow) or max_depth == 0 or item == items:
then it gets all three examples right.
来源:https://stackoverflow.com/questions/59903905/control-recursion-on-nested-lists-strings-without-checking-for-the-type