简体   繁体   中英

Remove empty nested lists within list

See below for the exact code. Basically, I am trying to take information from a csv file and create a list with one of the columns that has all the usernames (with no blanks or duplicates). I am able to get a list of all the usernames, but I can not find a way to remove the blanks. I have tried both filter as well as other methods, but can't seem to get it right. My code is:

with open('test.csv') as f:
reader = csv.DictReader(f)
initialExport = []
for row in reader:
    iE = [row['Computer Name'], row['Username']]
    initialExport.append(iE)

for i in initialExport:
    i.pop(0)
finalExport = filter(None, initialExport)
print(finalExport)

Rather than filtering it out, why not just avoid adding blank entries in the first place:

for row in reader:
    if row['Username']:
        iE = [row['Computer Name'], row['Username']]
        initialExport.append(iE)

initialExport is a list of (singleton) lists when you try to filter them. Some of these lists might contain the empty string. That does not make them empty lists! So their truthiness is true no matter what. You could filter them out via:

finalExport =  [l for l in initialExport if l[0]]

But why add the Computer Name column in the first place if you just pop it? And why make a nested list if you are just interested in one element:

finalExport = [row['Username'] for row in reader if row['Username']]

This shows a way to remove empty lists, empty tuples and lists containing only empty lists from lst. The code below will not remove:

  • empty nested tuples (with one or more levels)
  • empty nested lists with more than two levels

Confer the last two entries of lst.

import collections

lst = [1, 2, "3", "three", [], [1, 2, "3"], [[], []], 4,
       [[1], []], [[], [], []], 5, "6", (1,2), 7, (),
       ((), ()), [[[]]]]

for index, item in enumerate(lst):
    # if it is an empty list [] or tuple ()
    if not item:
        del lst[index]
    # if it is a list containing only empty sublists [[], [], ...]
    elif isinstance(item, collections.MutableSequence):
        if not [i for sublist in item for i in sublist]:
            del lst[index]

print(lst)

Output:

[1, 2, '3', 'three', [1, 2, '3'], 4, [[1], []], 5, '6', (1, 2), 7, ((), ()), [[[]]]]

Four elements are removed from lst in the above example, namely [], [[], []], [[], [], []] and ().

purge(list, [elements to purge]) will recursively purge all copies of element from the list and any sublists, including any elements created by removing deeper elements ( [[[], []]] will be entirely removed). Because we're modifying the list in-place, we have to restart at our current depth every time we remove an element:

def purge(lst, bad):
    restart = True
    while restart:
        restart = False
        for index, ele in enumerate(lst[:]):
            if ele in bad:
                del lst[index]
                restart = True
                break
            elif isinstance(ele, list):
                purge(ele, bad)
                if lst[index] in bad:
                    del lst[index]
                    restart = True
                    break

Examples:

>>> lst = [[[[], [[],[]]]]]
>>> purge(lst, [[]])
[]

>>> lst = [1, 2, "3", "three", [], [1, 2, "3"], [[], []], 4,
       [[1], []], [[], [], []], 5, "6", (1,2), 7, [[[]]]]
>>> purge(lst, [[]])
[1, 2, '3', 'three', [1, 2, '3'], 4, [[1]], 5, '6', (1, 2), 7]
>>> purge(lst, ['3'])
[1, 2, 'three', [1, 2], 4, [[1]], 5, '6', (1, 2), 7]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM