Удалить дубликаты из вложенного списка на основе строки и значения
У меня есть список:
[['john', 14, 'USA'],['john', 27, 'USA'],['paul', 17, 'USA'],['paul', 36, 'USA']]
И нужно получить результат:
[['john', 27, 'USA'],['paul', 36, 'USA']]
Это означает удаление дубликатов на основе позиции 0, но сохранить их с более высоким значением в позиции 1.
Я знаю, как удалять дубликаты в обычных списках с помощью set()
, но как я могу применить эти 2 условия? Я думал о чем-то, но я мог бы быть очень медленным, так как реальные списки, которые я буду использовать, очень большие.
Я уже пытался удалить дубликаты только по именам, но я озадачен тем, что сохраняю одно значение с более высоким значением.
Благодаря!
- Есть ли разница между типом и классом?
- Чтобы подсчитать частоту слова в нескольких документах python
- Назначение функции вызова без скобок python
- SQL-подобные MAX и GROUP BY над списком dicts
- Форматирование рабочих характеристик с использованием .json ()
Мне нравится решение Kasra, но jsut дать другой способ сделать это:
from collections import defaultdict l=[['john', 14, 'USA'], ['john', 27, 'USA'], ['paul', 17, 'USA'], ['paul', 36, 'USA']] key=defaultdict(list) for n,a,c in l: key[(n,c)].append(a) f_list = [[k[0],max(la),k[1]] for k,la in key.iteritems()]
Вы можете использовать itertools.groupby
для группировки ваших элементов с помощью первой функции index и max
с помощью подходящей key
для выбора max на основе второго элемента:
>>> from itertools import groupby >>> l=[['john', 14, 'USA'], ['john', 27, 'USA'], ['paul', 17, 'USA'], ['paul', 36, 'USA']] >>> [max(g ,key=lambda x:x[1]) for _,g in groupby(sorted(l),lambda x: x[0])] [['john', 27, 'USA'], ['paul', 36, 'USA']]
Или, как более эффективный способ, вы можете использовать operators.itemgetter()
вместо lambda
:
>>> from operators import itemgetter >>> [max(g ,key=itemgetter(1)) for _,g in groupby(sorted(l),itemgetter(0))] [['john', 27, 'USA'], ['paul', 36, 'USA']]
пробуя мою руку на непонятном уровне питонов.
использование списков и словарных знаний i сортировка, слияние и переформатирование
a = [['john', 14, 'USA'],['john', 27, 'USA'],['paul', 17, 'USA'],['paul', 36, 'USA']] b = sorted(a, key=lambda x: x[0]) c = { x[0] : x[1:len(x)] for x in b } result = [[n] + c[n] for n in c]
Вы можете использовать OrderedDict и заменить значение, если мы найдем подписок с таким же именем с большим вторым подэлементом:
l = [['john', 14, 'USA'],['john', 27, 'USA'],['paul', 17, 'USA'],['paul', 36, 'USA']] from collections import OrderedDict d = OrderedDict() for sub in l: name = sub[0] if name in d: if sub[1] > d[name][1]: d[name] = sub else: d[name] = sub print(list(d.values())) [['john', 27, 'USA'], ['paul', 36, 'USA']]
Это O(n)
поскольку он не должен сортировать список, который является n log n
поэтому это будет масштабироваться лучше, чем любой метод с использованием отсортированного.
Если порядок не имеет значения, нормальный дикт будет в порядке:
d = {} for sub in l: name = sub[0] if name in d: if sub[1] > d[name][1]: d[name] = sub else: d[name] = sub print(d.values())
Если вы собираетесь сортировать, используя operator.itemgetter
, будет более эффективным:
from operator import itemgetter sorted(l,key=itemgetter(1))
Если вы хотите отсортировать исходный список:
l.sort(key=itemgetter(1))
- Один производитель нескольких потребителей
- Написание рекурсивной функции, которая возвращает цифру с самой длинной последовательной последовательностью
- Как правильно сохранить несколько файлов в django?
- Удалить nan и соответствующие элементы в двух массивах одинаковой длины
- Планирование асинхронной сопрограммы из другого потока
- Ускорение в петлеобразных структурах
- Что такое подсказки типа в Python 3.5
- Ошибка записи CSV на Python 3
- Как сделать мигающее текстовое поле в tkinter?
- Как изначально увеличить значение словарного элемента?
- СинтаксисError не исключается в Python 3