#python
Вопрос:
У меня есть динамический список :
[{'dashboard': 'AG', 'end_date': '2021-06-17 13:13:43', 'location': 'EC amp; pH Reading', 'zone_name': 'Zone 1 Left'},
{'dashboard': 'AG', 'end_date': '2021-06-17 12:40:06', 'location': 'Harvest', 'zone_name': 'Zone 2 Left'},
{'dashboard': 'AG', 'end_date': '2021-06-16 15:52:52', 'location': 'Harvest', 'zone_name': 'Zone 1 Left' },
{'dashboard': 'AG', 'end_date': '2021-06-16 15:45:51', 'location': 'Harvest', 'zone_name': 'Zone 1 Left'}]
Я хочу удалить дубликаты на основе имени зоны и местоположения.
В zone_name есть 3 значения. Я хочу удалить старую. Я отсортировал, используя конечную дату. То есть последнее будет на вершине.
Теперь мне нужно удалить повторяющееся значение на основе имени зоны и местоположения.
Это то, что я пробовал:
final_zone = []
res_list = []
for i in sortedArray:
if i["location"] not in final_zone:
sch.append(i)
final_zone.append(i["location"])
Какие изменения мне нужно сделать, чтобы удалить дубликат на основе имени зоны и местоположения.
То есть в левой зоне 1 есть 3 значения , мне нужно последнее
Комментарии:
1. Последняя. Я отсортировал это по дате окончания
Ответ №1:
Для общего подхода с несортированным списком:
from itertools import groupby
from operator import itemgetter
# sorting and grouping functions
f_sort = itemgetter("location", "zone_name", "end_date") # sort by descending
f_group = itemgetter("location", "zone_name") # group sorted by
result = [
next(g) for _, g in # only take latest of each group
groupby(sorted(array, key=f_sort, reverse=True), key=f_group)
]
Вот некоторая документация по используемым utils (все они очень удобны во многих случаях использования):
Ответ №2:
clean_list=[]
for elem in lst:
# control if an element with the same zone name and location
# is yet present in the clean list
yet_present= len([el for el in clean_list
if el['zone_name']==elem['zone_name']
if el['location']==elem['location']])>0
if not yet_present:
clean_list.append(elem)
выход:
[{'dashboard': 'AG',
'end_date': '2021-06-17 13:13:43',
'location': 'EC amp; pH Reading',
'zone_name': 'Zone 1 Left'},
{'dashboard': 'AG',
'end_date': '2021-06-17 12:40:06',
'location': 'Harvest',
'zone_name': 'Zone 2 Left'},
{'dashboard': 'AG',
'end_date': '2021-06-16 15:52:52',
'location': 'Harvest',
'zone_name': 'Zone 1 Left'}]
Комментарии:
1. Вы спасли мне день. Спасибо
2. Если мой ответ полезен, пожалуйста, поддержите и/или примите его.
3. Нужно 15 репутации, чтобы поднять голос. у меня этого нет, поэтому я не могу этого сделать
4. Вы можете принять его (инструкции: meta.stackexchange.com/a/5235/645001 )
Ответ №3:
Вы можете просто просмотреть список и запомнить индексы, которые хотите сохранить.
keepers = {}
for i in range(len(sorted_array)):
keepers(sorted_array[i]['location'])=i ## Will be overwritten if the zone_name repeats
final_array = []
for i in keepers.values():
final_array.append(sorted_array[i])
В качестве бонуса вы получаете список всех зон внутри keepers.keys()
.
Но ваш подход также может сработать. Просто измените sch.append(i)
res_list.append(i)
и измените порядок iterable ( for i in sorted_array[::-1]
), чтобы сохранялся последний, а не первый.
Ответ №4:
Другие ответы работают, но я хочу добавить решение, используя Pandas
вы можете создать фрейм данных из своего списка словарей:
import pandas as pd
d = [{'dashboard': 'AG', 'end_date': '2021-06-17 13:13:43', 'location': 'EC amp; pH Reading', 'zone_name': 'Zone 1 Left'}, {'dashboard': 'AG', 'end_date': '2021-06-17 12:40:06', 'location': 'Harvest', 'zone_name': 'Zone 2 Left'},
{'dashboard': 'AG', 'end_date': '2021-06-16 15:52:52', 'location': 'Harvest', 'zone_name': 'Zone 1 Left' },
{'dashboard': 'AG', 'end_date': '2021-06-16 15:45:51', 'location': 'Harvest', 'zone_name': 'Zone 1 Left'}]
df = pd.DataFrame(d)
Вот как выглядит df:
dashboard end_date location zone_name
0 AG 2021-06-17 13:13:43 EC amp; pH Reading Zone 1 Left
1 AG 2021-06-17 12:40:06 Harvest Zone 2 Left
2 AG 2021-06-16 15:52:52 Harvest Zone 1 Left
3 AG 2021-06-16 15:45:51 Harvest Zone 1 Left
Что-то вроде таблицы в Excel.
Теперь с помощью одной строки вы можете делать именно то, что хотите:
df.sort_by("end_date").drop_duplicates(["location", "zone_name"], keep="last")
выход:
dashboard end_date location zone_name
2 AG 2021-06-16 15:52:52 Harvest Zone 1 Left
1 AG 2021-06-17 12:40:06 Harvest Zone 2 Left
0 AG 2021-06-17 13:13:43 EC amp; pH Reading Zone 1 Left