У меня есть список кортежей следующим образом:
data = [
('A', '59', '62'), ('A', '2', '6'), ('A', '87', '92'),
('A', '98', '104'), ('A', '111', '117'),
('B', '66', '71'), ('B', '25', '31'), ('B', '34', '40'), ('B', '46', '53'),
('B', '245', '251'), ('B', '235', '239'), ('B', '224', '229'), ('B', '135', '140'),
('C', '157', '162'), ('C', '203', '208'),
('D', '166', '173'), ('D', '176', '183'),
('E', '59', '62'), ('E', '2', '6'), ('E', '87', '92'), ('E', '98', '104'), ('E', '111', '117')
]
Они соответствуют подмножеству большего набора данных, поэтому я извлек, как указано выше, чтобы упростить этот пост. Первый элемент каждого кортежа, то есть A, B, C, D, E ... является идентификатором и может присутствовать в нескольких копиях.
Я хотел бы извлечь для каждой ID / категории (A, B, C, D, E ...):
1 - минимум от 2-го элемента кортежа
2 - максимум от 3-го элемента кортежа
Окончательный список вывода должен выглядеть следующим образом:
A: min = 2, max = 117
B: min = 25, max = 251
C: min = 157, max = 208
D: min = 166, max = 183
E: min = 2, max = 117
Я попробовал подход, основанный на этом посте: Как удалить дубликаты из списка кортежей, когда важен порядок
Я упростил тестирование, используя кортежи только с первыми 2 элементами и извлекая только минимум.
Вывод выглядит так:
('A', '111')
('B', '135')
('C', '157')
('D', '166')
('E', '111')
Должно быть:
('A', '2')
('B', '25')
('C', '157')
('D', '166')
('E', '2')
Я ищу подход, который бы работал с полным примером «тройной кортеж», чтобы избежать разделения данных на несколько подмножеств.
Большое спасибо за ваше время.
РЕДАКТИРОВАТЬ 1 - 31/10/2018
Здравствуйте,
см. Мое редактирование ниже, которое включает фрагмент кода, не включенный ранее. Это дает ошибочные минимальные значения в предыдущей части поста.
data_min_only = [('A', '59'), ('A', '2'), ('A', '87'), ('A', '98'), ('A', '111'), ('B', '66'), ('B', '25'), ('B', '34'), ('B', '46'), ('B', '245'), ('B', '235'), ('B', '224'), ('B', '135'), ('C', '157'), ('C', '203'), ('D', '166'), ('D', '176'), ('E', '59'), ('E', '2'), ('E', '87'), ('E', '98'), ('E', '111')]
from collections import OrderedDict
empty_dict = OrderedDict()
for item in data_min_only:
# Get old value in dictionary if exist
old = empty_dict.get(item[0])
# Skip if new item is larger than old
if old:
if item[1] > old[1]:
continue
else:
del d[item[0]]
# Assign
empty_dict[item[0]] = item
list(empty_dict.values())
Я думал, что проблема заключается в порядке значений кортежей для каждой категории (от наименьшего к наибольшему до итерации по data_min_only
.
Спасибо всем авторам за их быстрые ответы и предложения / решения! Сейчас я работаю над этим, чтобы попытаться понять и адаптировать их дальше.
РЕДАКТИРОВАТЬ 2 - 31/10/2018
Я подправил предложение @slider для получения различий между мин и макс. Я также попытался вывести этот результат в список, как показано ниже, но отображается только последний результат.
for k, g in groupby(sorted(data), key=lambda x: x[0]):
vals = [(int(t[1]), int(t[2])) for t in g]
print (max(i[1] for i in vals) - min(i[0] for i in vals))
test_lst = []
test_lst.append((max(i[1] for i in vals) - min(i[0] for i in vals)))
Я тоже пробовал это, но получил тот же результат:
for i in vals:
test_lst2 = []
test_lst2.append((max(i[1] for i in vals) - min(i[0] for i in vals)))
Для этого вида цикла, каков наилучший способ извлечь результаты в список?
Еще раз спасибо.
РЕДАКТИРОВАТЬ 3 - 31/10/2018
test_lst = []
for k, g in groupby(sorted(data), key=lambda x: x[0]):
vals = [(int(t[1]), int(t[2])) for t in g]
print (max(i[1] for i in vals) - min(i[0] for i in vals))
test_lst.append((max(i[1] for i in vals) - min(i[0] for i in vals)))
Решение для извлечения данных цикла - пустой список должен быть вне цикла. Пожалуйста, смотрите @slider комментарии для своего поста ниже.