Reputation: 1424
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))
Upvotes: 4
Views: 1128
Reputation: 2607
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)]]
Upvotes: 7
Reputation:
Why not just add an if
block to check if the first element in your tuple point
exists or is True
. You can also use list comprehension but I assume you are new to python.
oldList = [[(1,None),(2,45),(3,67)],[(1,None), (2,None), (3,None),(4,56),(5,78)],[(1, None),(2, 98)]]
newList = []
for data in oldList:
tempList = []
for point in data:
if point[1]:
tempList.append(point)
newList.append(tempList)
print newList
>>> [[(2, 45), (3, 67)], [(4, 56), (5, 78)], [(2, 98)]]
Upvotes: 0
Reputation: 1325
List comprehensions:
>>> newList = [[x for x in lst if None not in x] for lst in oldList]
>>> newList
[[(2, 45), (3, 67)], [(4, 56), (5, 78)], [(2, 98)]]
>>>
Upvotes: 0
Reputation: 23003
Tuple are immutable, therefore you cannot modify them. You have to replace them. By far the most canonical way to do this, is to make use of Python's list comprehension:
>>> oldList = [[(1,None),(2,45),(3,67)],[(1,None), (2,None), (3,None),(4,56),(5,78)],[(1, None),(2, 98)]]
>>> [[tup for tup in sublist if not None in tup] for sublist in oldList]
[[(2, 45), (3, 67)], [(4, 56), (5, 78)], [(2, 98)]]
>>>
Upvotes: 0
Reputation: 48120
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)]]
Upvotes: 1