Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering nested list

I want to filter a nested list by another list which can be of variable length. If any item of a sublist matches any element of the filter list, the sublist should be excluded. The following code works for me but is there a "cleaner" solution for this task?

the_list = [['blue'], ['blue', 'red', 'black'], ['green', 'yellow'], ['yellow', 'green'], ['orange'], ['white', 'gray']]
filters = ['blue', 'white']

filtered_list = []
for sublist in the_list:
    for item in sublist:
        if item in filters:
            break
        filtered_list.append(sublist)
        break

Expected output:

filtered_list = [['green', 'yellow'], ['yellow', 'green'], ['orange']]
like image 956
tenac Avatar asked Jan 13 '18 02:01

tenac


3 Answers

Perhaps a bit more semantic would be to use any.

for sublist in the_list:
    if any(item in filters_exclude for item in sublist):
        continue
    filtered_list.append(sublist)

Maybe overkill, but you could even factor that into its own function then use the builtin filter

def good_list(some_list):
    return not any(item in filters_exclude for item in some_list)

filtered_list = filter(good_list, the_list)

This should accomplish the goal you described. However, the code you wrote has potential issues, as mentioend in the comments.

like image 182
sytech Avatar answered Oct 19 '22 13:10

sytech


You can use list comprehension:

the_list = [['blue'], ['blue', 'red', 'black'], ['green', 'yellow'],['orange'], ['white', 'gray']]
filters = ['blue', 'white']
final_l = [i for i in the_list if not any(b in filters for b in i)]

Output:

[['green', 'yellow'], ['orange']]

Or, using filter:

final_l = filter(lambda x:not any(b in filters for b in x), the_list)
like image 41
Ajax1234 Avatar answered Oct 19 '22 12:10

Ajax1234


You can use filter and map to make this a "one-liner". It doesn't improve readability, but it works:

filters_exclude = [2, 4]
initial_list = [[1, 2, 3, 4], [1, 2, 3], [2, 3, 4, 5]]

final = list(map(lambda x: filter(lambda y: y not in filters_exclude, x), initial_list)

Example:

>>> filters_exclude = [2, 4]
>>> map(lambda x: filter(lambda y: y not in filters_exclude, x), [[1, 2, 3, 4], [1, 2, 3]])
[[1, 3], [1, 3]]
like image 37
AetherUnbound Avatar answered Oct 19 '22 13:10

AetherUnbound