Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter a list of lists of tuples

Tags:

python

filter

I have a list of lists of tuples:

oldList = [[(1,None),(2,45),(3,67)],[(1,None), (2,None), (3,None),(4,56),(5,78)],[(1, None),(2, 98)]]

I would like to filter any instance of "None":

newList = [[(2,45),(3,67)], [(4,56),(5,78)], [(2, 98)]]

The closest I've come is with this loop, but it does not drop the entire tuple (only the 'None') and it also destroys the list of lists of tuples structure:

newList = []
for data in oldList:
    for point in data:
        newList.append(filter(None,point))
like image 846
mk8efz Avatar asked Feb 06 '23 18:02

mk8efz


2 Answers

The shortest way to do this is with a nested list comprehension:

>>> newList = [[t for t in l if None not in t] for l in oldList]
>>> newList
[[(2, 45), (3, 67)], [(4, 56), (5, 78)], [(2, 98)]]

You need to nest two list comprehensions because you are dealing with a list of lists. The outer part of the list comprehension [[...] for l in oldList] takes care of iterating through the outer list for each inner list contained. Then inside the inner list comprehension you have [t for t in l if None not in t], which is a pretty straightforward way of saying you want each tuple in the list which does not contain a None.

(Arguably, you should choose better names than l and t, but that would depend on your problem domain. I've chosen single-letter names to better highlight the structure of the code.)

If you are unfamiliar or uncomfortable with list comprehensions, this is logically equivalent to the following:

>>> newList = []
>>> for l in oldList:
...     temp = []
...     for t in l:
...         if None not in t:
...             temp.append(t)
...     newList.append(temp)
...
>>> newList
[[(2, 45), (3, 67)], [(4, 56), (5, 78)], [(2, 98)]]
like image 61
user108471 Avatar answered Feb 08 '23 08:02

user108471


You need to create a temporary list list within you first for loop for maintaining the nested structure of list as:

>>> new_list = []
>>> for sub_list in oldList:
...     temp_list = []
...     for item in sub_list:
...         if item[1] is not None:
...             temp_list.append(item)
...     new_list.append(temp_list)
...
>>> new_list
[[(2, 45), (3, 67)], [(4, 56), (5, 78)], [(2, 98)]]

Alternatively, better way to achieve the same is using list comprehension expression as:

>>> oldList = [[(1,None),(2,45),(3,67)],[(1,None), (2,None), (3,None),(4,56),(5,78)],[(1, None),(2, 98)]]
>>> [[(k, v) for k, v in sub_list if v is not None ] for sub_list in oldList]
[[(2, 45), (3, 67)], [(4, 56), (5, 78)], [(2, 98)]]
like image 31
Moinuddin Quadri Avatar answered Feb 08 '23 07:02

Moinuddin Quadri