2016-12-30 7 views
2

У меня есть список кортежей, глядя, как items = [(id, date), ...]Список кортежей: удалить кортежи путем сравнения элемента, если у них есть еще один идентичный элемент

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

Например:

items = [('1', '12/2/2016'), ('2', '12/20/2016'), ('1', '12/24/2016')] 

# Apply filter comparing tuples with identical [0] element based off [1] element 

items = [('2', '12/20/2016'), ('1', '12/24/2016')] 

Я ищу самый элегантный и «вещий» решение этой проблемы, спасибо!

+0

сортировать их, а затем использовать 'itertools.groupby' группировать их по id, затем используйте 'max' с ключевой функцией, чтобы найти самую последнюю дату. Я думаю, вы можете использовать 'datetime.date' для этого, но мне нужно было бы проверить –

ответ

0

Мы будем сортировать их, а затем сгруппировать их с помощью itertools.groupby затем использовать max, чтобы найти самую последнюю дату. Мы напишем ключевую функцию, которая берет один из этих кортежей и возвращает объект datetime.date.

from datetime import date 
from itertools import groupby 

def make_date(t): 
    month, day, year = map(int, t[1].split('/')) 
    return date(year, month, day) 

items = [max(g, key=make_date) for k, g in groupby(sorted(items, key=lambda x: int(x[0])), key=lambda x: x[0])] 

EDIT: Мы просто получить t[-1] получить последний элемент кортежа и использовать datetime.datetime.strptime, чтобы Получить DATETIME

from datetime import datetime 
from itertools import groupby 

items = [max(g, key=lambda x: datetime.strptime(x[-1], '%m/%d/%Y %H:%M:%S')) for k, g in groupby(sorted(items, key=lambda x: int(x[0])), key=lambda x: x[0])] 
+0

. Как бы я подошел к этому с большим кортежем (размер 5), Я попытался опустить ненужные данные в своем оригинальном посте, но мои фактические данные выглядят примерно так: '('104587520', '13347465', '17776122', 'Update', '12/29/2016 13:32:45 ')' Где tuple [0] - это идентификатор, на который я фильтрую, и tuple [5] - это дата, которую я сравниваю –

+0

@naterobo см. Мое редактирование –

3

Один из подходов - просто преобразовать в словарь и обратно (если вам это действительно нужно как список кортежей - или оставить его как dict).
Если кортежи не в хронологическом порядке, то вы можете просто sorted по дате:

>>> from datetime import datetime 
>>> items = [('1', '12/2/2016'), ('2', '12/20/2016'), ('1', '12/24/2016')] 
>>> d = dict(sorted(items, key=lambda x: datetime.strptime(x[1], '%m/%d/%Y'))) 
>>> items = list(d.items()) 
[('2', '12/20/2016'), ('1', '12/24/2016')] 
+0

Так что это зависит от' dict() 'игнорируя все, кроме первого кортежа с тем же самым первым элементом (ключ)? Я не знал об этом поведении. –

+0

'dict' ключи уникальны, поэтому любой будущий' ключ' перезаписывает предыдущее 'значение',' sorted' гарантирует, что последний 'ключ' имеет последнюю' дату' – AChampion