Somnath
Somnath

Reputation: 49

Filtering records from lists

I am new to python and wanted to have some help, would appreciate if someone could help,

I have a below python list of list, and I want to form a new list which will contain the last sublist based on first element of sublist, for ex. ISIN=BE0974302342, I want to add only ['BE0974302342', 21, 19, 0, 2, 0] to new list and ignore all first occurrences, I thought of using for loops to compare first element of every sublist with the first element of the second sublist, but that would not be a clean way, could this be achieved using list comprehension or some builtin method?

my_list = [['BE0974302342', 21, 0, 0, 0, 0], 
           ['BE0974302342', 21, 19, 0, 0, 0], 
           ['BE0974302342', 21, 19, 0, 2, 0], 
           ['FR0000073843', 22, 19, 0, 2, 0], 
           ['FR0000073843', 22, 20, 0, 2, 0], 
           ['FR0000073843', 22, 20, 0, 2, 0], 
           ['FR0000076861', 21, 20, 0, 2, 0], 
           ['FR0000076861', 21, 18, 0, 2, 0], 
           ['FR0000076861', 21, 18, 3, 2, 0], 
           ['FR0000076861', 21, 18, 3, 3, 0]]

 new_list = [['BE0974302342', 21, 19, 0, 2, 0], 
             ['FR0000073843', 22, 20, 0, 2, 0], 
             ['FR0000076861', 21, 18, 3, 3, 0]]

Upvotes: 1

Views: 81

Answers (4)

Óscar López
Óscar López

Reputation: 236004

Here's an alternative approach, which doesn't require itertools:

tmp = { x[0]:x for x in my_list }
new_list = list(tmp.values())

The tmp dict contains the last occurrence of the first element in the sublists. The only catch is that the sublists will appear in an order different from the original input:

new_list
=> [['FR0000073843', 22, 20, 0, 2, 0],
    ['FR0000076861', 21, 18, 3, 3, 0],
    ['BE0974302342', 21, 19, 0, 2, 0]]

Upvotes: 2

DirtyBit
DirtyBit

Reputation: 16772

one-liner (without using any import):

print(list({(x[0]): x for x in my_list}.values()))

OUTPUT:

[['BE0974302342', 21, 19, 0, 2, 0], ['FR0000073843', 22, 20, 0, 2, 0], 
 ['FR0000076861', 21, 18, 3, 3, 0]]

Elaboration:

The idea is to map every first element of the nested list with the list itself as a key-val pair, since dict can not have duplicate keys it will handle it for us:

print({x[0]: x for x in my_list})  

Would return something like:

{'BE0974302342': ['BE0974302342', 21, 19, 0, 2, 0], 'FR0000073843': ['FR0000073843', 22, 20, 0, 2, 0], 'FR0000076861': ['FR0000076861', 21, 18, 3, 3, 0]}

Now we, already have the unique key-val paired of lists, getting the values from the dict would get us the unique nested lists:

print({x[0]: x for x in my_list}.values())

Which would give us a dict of list:

dict_values([['BE0974302342', 21, 19, 0, 2, 0], ['FR0000073843', 22, 20, 0, 2, 0], ['FR0000076861', 21, 18, 3, 3, 0]])

We can convert it to a list now:

print(list({(x[0]): x for x in my_list}.values()))

This would simply get us the required unique lists based on the first element inside them:

[['BE0974302342', 21, 19, 0, 2, 0], ['FR0000073843', 22, 20, 0, 2, 0], 
 ['FR0000076861', 21, 18, 3, 3, 0]]

Upvotes: 2

yatu
yatu

Reputation: 88236

You could use itertools.groupby to group the sublists by the first element, and keep the last sublist of each group:

from itertools import groupby
from operator import itemgetter

[list(v)[-1] for _,v in groupby(my_list, key=itemgetter(0))]

Output

[['BE0974302342', 21, 19, 0, 2, 0],
 ['FR0000073843', 22, 20, 0, 2, 0],
 ['FR0000076861', 21, 18, 3, 3, 0]]

Upvotes: 4

Shuvojit
Shuvojit

Reputation: 1470

my_list = [['BE0974302342', 21, 0, 0, 0, 0], 
           ['BE0974302342', 21, 19, 0, 0, 0], 
           ['BE0974302342', 21, 19, 0, 2, 0], 
           ['FR0000073843', 22, 19, 0, 2, 0], 
           ['FR0000073843', 22, 20, 0, 2, 0], 
           ['FR0000073843', 22, 20, 0, 2, 0], 
           ['FR0000076861', 21, 20, 0, 2, 0], 
           ['FR0000076861', 21, 18, 0, 2, 0], 
           ['FR0000076861', 21, 18, 3, 2, 0], 
           ['FR0000076861', 21, 18, 3, 3, 0]]

my_list_dict = {}
new_list = []

# Unique Items with id as key and rest as values
for item in my_list:
    my_list_dict[item[0]] = item[1:]

# Convert them back to a list
for k,v in my_list_dict.items():
    new_list.append([k,*v])

print(new_list)

Upvotes: 3

Related Questions