Удалить дубликаты в списке кортежей на основе максимального значения - PullRequest
0 голосов
/ 07 сентября 2018

Предположим, у меня есть список tuples, например:

[('Machine1', 88), ('Machine2', 90), ('Machine3', 78), ('Machine1', 90), ('Machine3', 95)]

И я хочу отфильтровать список так, чтобы у меня были только самые высокие значения, относящиеся к каждой tuple паре. Таким образом, в этом примере отфильтрованный список будет:

[('Machine2', 90),('Machine1', 90), ('Machine3', 95)]

Я хочу удалить дубликаты по наибольшему значению. Я знаю, set удаляет только точные дубликаты, поэтому я не смогу сделать это здесь. Я подумал, что другой метод, который я мог бы использовать, это использовать dictionary и обновлять его, повторяя список, если было замечено более высокое значение. Тем не менее, что является более питоническим способом приблизиться к этому?

Ответы [ 3 ]

0 голосов
/ 07 сентября 2018

Одно решение с простым dict

d = {}
for machine, value in l:
    d[machine] = max(d.get(machine, -float('inf')), value)
print(list(d.items()))

Выходы

[('Machine1', 90), ('Machine2', 90), ('Machine3', 95)]

Использование pandas (для удовольствия)

>>> pd.DataFrame(l).groupby(0).max().to_dict()[1].items()
[('Machine1', 90), ('Machine2', 90), ('Machine3', 95)]
0 голосов
/ 07 сентября 2018

В itertools можно использовать оператор groupby:

>>> import itertools as it
>>> [ (k, max( list(zip(*g))[1])   ) for k,g in it.groupby(sorted(data), key=lambda m: m[0])]

Помните, что данные отсортированы, поэтому вы также можете сделать:

>>> [ (k, list(zip(*g))[1][-1]   ) for k,g in it.groupby(sorted(data), key=lambda m: m[0])]
0 голосов
/ 07 сентября 2018

Вот одно решение, использующее collections.defaultdict. Идея состоит в том, чтобы перебрать ваш список кортежей и добавить в списки. Затем используйте zip с map + max для создания желаемого результата.

from collections import defaultdict

L = [('Machine1', 88), ('Machine2', 90), ('Machine3', 78),
     ('Machine1', 90), ('Machine3', 95)]

d = defaultdict(list)

for name, num in L:
    d[name].append(num)

res =  list(zip(d, map(max, d.values())))

Результат

[('Machine1', 90), ('Machine2', 90), ('Machine3', 95)]
...