Converting this loop to a list comprehension

71 Views Asked by At

I would like to generate a list of unique Ids by only keeping the list that has the minimum value in element 2.

For example, given the list:

list1 = [['Id1', 1, 40],['Id1', 2, 30],['Id2', 10,40]]`

Expected output:

    [['Id1', 1, 40],['Id2', 10,40]]

Here's my working example, but it's pretty clunky. I think it could probably be done with a single list comprehension.

list1 = [['Id1', 1, 40],['Id1', 2, 30],['Id2', 10,40]]

unique_list = list(set([x[0] for x in list1]))
unique_list = [[x] for x in unique_list]

for x in unique_list:
    id = x[0]
    min_val = min([y[1:] for y in list1 if y[0] == id])
    x.extend(min_val )

print unique_list
2

There are 2 best solutions below

1
On BEST ANSWER

You can use itertools.groupby to group by the first element in the sublists, the you can get the min with a key argument to sort by the remaining elements in the sublist.

>>> from itertools import groupby
[min(list(g), key = lambda i: i[1:]) for k, g in groupby(list1, lambda i: i[0])]
[['Id1', 1, 40], ['Id2', 10, 40]]
0
On

A very naive approach but easily understandable.

list1 = [['Id1', 1, 40],['Id1', 2, 30],['Id2', 10,40]]
unique_list = []
for list_element in list1:
    appendable = True
    for temp_list in unique_list:
        if list_element[0] == temp_list[0]:
            if temp_list[1] < list_element[1]:
               appendable = False
            else:
               unique_list.remove(temp_list)
    if appendable == True:
        unique_list.append(list_element)
    unique_list.sort()

print unique_list