Удалить повторяющийся элемент в списке списка в Python - PullRequest
0 голосов
/ 26 ноября 2018

У меня есть такой список:

[{'score': '92', 'imageId': '6184de26-e11d-4a7e-9c44-a1af8012d8d0', 'label': 'Door'},
 {'score': '61', 'imageId': '6184de26-e11d-4a7e-9c44-a1af8012d8d0', 'label': 'Sliding Door'}]

Я хочу удалить дубликаты изображений на основе их imageId.Таким образом, в приведенном выше примере imageID 6184de26-e11d-4a7e-9c44-a1af8012d8d0 присутствует 2 раза (оставьте тот, у кого самый высокий балл).

Как это сделать в Python?

Ответы [ 4 ]

0 голосов
/ 26 ноября 2018

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

import pandas as pd

my_list = [
    {'score': '192', 'imageId': '6184de26-e11d-4a7e-9c44-a1af8012d8d0', 'label': 'Door'},
    {'score': '61', 'imageId': 'fffffe26-e11d-4a7e-9c44-a1af8012d8d0', 'label': 'misc'},
    {'score': '761', 'imageId': '6184de26-e11d-4a7e-9c44-a1af8012d8d0', 'label': 'Sliding Door'},
    {'score': '45', 'imageId': '6184de26-e11d-4a7e-9c44-a1af8012d8d0', 'label': 'Door'},
]

# create dataframe
df = pd.DataFrame(my_list)

# your score is string! convert it to int
df['score'] = df['score'].astype('int')

# sort values
df = df.sort_values(by=['imageId', 'score'], ascending=False)

# drop duplicates
df = df.drop_duplicates('imageId', keep='first')


    imageId                                 label           score
1   fffffe26-e11d-4a7e-9c44-a1af8012d8d0    misc            61
2   6184de26-e11d-4a7e-9c44-a1af8012d8d0    Sliding Door    761
0 голосов
/ 26 ноября 2018

Использование groupby,

from itertools import groupby
new_list = [max(list(l),key=lambda x:x['score']) for _,l in groupby(sorted(lst,key=lambda x:x['imageId']),lambda x:x['imageId'])]

Исполнение:

In [41]: lst = [{'score': '92', 'imageId': '6184de26-e11d-4a7e-9c44-a1af8012d8d0', 'label': 'Door'}, {'score': '61', 'imageId': '6184de26-e11d-4a7e-9c44-a1af8012d8d0', 'label': 'Sliding Door'}]

In [42]: print [max(list(l),key=lambda x:x['score']) for g,l in groupby(lst,lambda x:x['imageId'])]    
[{'score': '92', 'label': 'Door', 'imageId': '6184de26-e11d-4a7e-9c44-a1af8012d8d0'}]
0 голосов
/ 26 ноября 2018

Я предлагаю вам немного улучшить свой пример, чтобы:

  • он проверял числовые сравнения
  • он имел непоследовательные "дублирующие" элементы

Я бы создал маркер dict с id в качестве ключа и sublist в качестве значения.Зацикливание на входе и перезапись вхождения dict, если значение выше (не забудьте привести к целому числу)

my_list = [
    {'score': '192', 'imageId': '6184de26-e11d-4a7e-9c44-a1af8012d8d0', 'label': 'Door'},
    {'score': '61', 'imageId': 'fffffe26-e11d-4a7e-9c44-a1af8012d8d0', 'label': 'misc'},
    {'score': '761', 'imageId': '6184de26-e11d-4a7e-9c44-a1af8012d8d0', 'label': 'Sliding Door'},
    {'score': '45', 'imageId': '6184de26-e11d-4a7e-9c44-a1af8012d8d0', 'label': 'Door'},
]

import collections

d = dict()

for subdict in my_list:
    score = int(subdict['score'])
    image_id = subdict['imageId']
    if image_id not in d or int(d[image_id]['score']) < score:
        d[image_id] = subdict

new_list = list(d.values())

результат (порядок может измениться при использовании словаря):

[{'imageId': 'fffffe26-e11d-4a7e-9c44-a1af8012d8d0',
  'label': 'misc',
  'score': '61'},
 {'imageId': '6184de26-e11d-4a7e-9c44-a1af8012d8d0',
  'label': 'Sliding Door',
  'score': '761'}]
0 голосов
/ 26 ноября 2018

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

my_list = [
    {'score': '92', 'imageId': '6184de26-e11d-4a7e-9c44-a1af8012d8d0', 'label': 'Door'},
    {'score': '61', 'imageId': '6184de26-e11d-4a7e-9c44-a1af8012d8d0', 'label': 'Sliding Door'}
]

by_id = {}
for element in my_list:
   imageId = element['imageId']
   if imageId in by_id:
       if int(by_id[imageId]['score']) < int(element['score']):
           # Replace because of higher score
           by_id[imageId] = element
   else:
       # Insert new element
       by_id[imageId] = element

print(list(by_id.values()))
...