Lokesh
Lokesh

Reputation: 89

Removing empty sublists from a nested list

I have the following nested list:

mynestedlist = [[[], [], [], ['Foo'], [], []], [[], ['Bar'], [], []], ['FOO'], 'BAR']

I want to flatten it to the outermost items, which would give me 4 items inside the main list. However, I only want the items with text and want to remove the empty bracket lists.

Desired output:

mynestedlist = [[['Bar']], ['FOO'], 'BAR']

I have tried the following:

newlist = []
for i in mynestedlist:
    for sub in i:
        if sub != []:
            newlist.append(sub)

However, I'm getting the following output:

[['Foo'], ['bar'], 'FOO', 'B', 'A', 'R']

Upvotes: 1

Views: 1034

Answers (3)

SpaceKatt
SpaceKatt

Reputation: 1401

With some recursion it is possible to remove empty lists at any depth while preserving string elements.

def remove_nested_null(a):
    if not isinstance(a, list):
        return a

    a = map(remove_nested_null, a)
    a = list(filter(None, a))

    return a

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1121138

You have a mix of lists and strings, both of which are iterables. You need to explicitly test for lists here, and either recurse or use a stack:

def clean_nested(l):
    cleaned = []
    for v in l:
        if isinstance(v, list):
            v = clean_nested(v)
            if not v:
                continue
        cleaned.append(v)
    return cleaned

Demo:

>>> mynestedlist = [[[], [], [], ['Foo'], [], []], [[], ['Bar'], [], []], ['FOO'], 'BAR']
>>> clean_nested(mynestedlist)
[[['Foo']], [['Bar']], ['FOO'], 'BAR']

Note that this solution removes all but the outermost list if there are empty lists inside empty lists:

>>> nested_empty = [[[],[],[],[],[],[]],[[],['Bar'],[], []], ['FOO'], 'BAR']
>>> clean_nested(nested_empty)
[[['Bar']], ['FOO'], 'BAR']
>>> all_nested_empty = [[[],[],[],[],[],[]],[[],[],[], []], []]
>>> clean_nested(all_nested_empty)
[]

Upvotes: 6

user2390182
user2390182

Reputation: 73450

The following will do:

def del_empty(lst):
    if isinstance(lst, list):
        return [del_empty(sub) for sub in lst if sub != []]
    return lst

>>> del_empty(mynestedlist)
[[['Foo']], [['Bar']], ['FOO'], 'BAR']

Upvotes: 1

Related Questions