Reputation: 105
How to from this list:
list = [
[],
['', 'subitem'],
[[]],
'item',
[
'item',
'item',
[''],
[]
],
[]
]
I can get this:
list = [
['subitem'],
'item',
[
'item',
'item'
]
]
How do I remove recursively all empty nested lists, zero-strings, and lists with nested zero-strings?
Upvotes: 2
Views: 1825
Reputation: 97918
def purify(l):
for (i, sl) in enumerate(l):
if type(sl) == list:
l[i] = purify(sl)
return [i for i in l if i != [] and i != '']
l1 = [ [], ['', 'subitem'], [[]], 'item', [ 'item', 'item', [''], [] ], [] ]
print purify(l1)
Prints:
[['subitem'], 'item', ['item', 'item']]
Upvotes: 4
Reputation: 4079
A one-liner:
def remove_empty(l):
return tuple(filter(lambda x:not isinstance(x, (str, list, tuple)) or x, (remove_empty(x) if isinstance(x, (tuple, list)) else x for x in l)))
Upvotes: 3
Reputation: 7167
Maybe something like this?
#!/usr/local/cpython-3.3/bin/python
'''Demonstrate a way of removing empty lists and empty strings from a nested list'''
import pprint
def remove_empty_recursive(input_obj):
'''Remove empty lists and strings - worker function'''
if isinstance(input_obj, str):
if input_obj:
# it's a nonempty string, pass it through
return input_obj
else:
# string is empty, delete it
return None
elif isinstance(input_obj, list):
if input_obj:
new_obj = []
for element in input_obj:
subresult = remove_empty_recursive(element)
if subresult is None:
pass
else:
new_obj.append(subresult)
if new_obj:
return new_obj
else:
return None
else:
return None
def remove_empty(list_):
'''Remove empty lists and strings - user callable portion'''
result = remove_empty_recursive(list_)
return result
def for_comparison():
'''Show what the O.P. wanted, for comparison's sake'''
list_ = [
['subitem'],
'item',
[
'item',
'item'
]
]
return pprint.pformat(list_)
def main():
'''Main function'''
list_ = [
[],
['', 'subitem'],
[[]],
'item',
[
'item',
'item',
[''],
[]
],
[]
]
result = remove_empty(list_)
print('actual result:')
pprint.pprint(result)
print('desired result:')
print(for_comparison())
main()
If that's not quite it, you may want to share a more detailed example that this fails on.
Upvotes: 1
Reputation: 1040
Recursion:
def remove_lst(lst):
if not isinstance(lst, list):
return lst
else:
return [x for x in map(remove_lst, lst) if (x != [] and x != '')]
Upvotes: 8