удаление дубликатов записей в python

#python #duplicates

#python #дубликаты

Вопрос:

Как я могу удалить дубликаты записей в следующей форме с помощью Python 3? Для переменной «string»:

 string = '{"information": [{"ID":"1111","name":"Smith","Age":"20"},       
             {"Age":"31","name":"Jane","ID":"2222"},
             {"ID":"1111","name":"Smith","Age":"20"},
             {"ID":"1111","Age":"20","name":"Smith"},
             {"ID":"3333","Age":"28","name":"Sam"}]}'
  

Требуемый вывод после удаления дубликатов:

 [{"ID":"1111","name":"Smith","Age":"20"}, 
 {"ID":"2222","Age":"31","name":"Jane"},
 {"ID":"3333","Age":"28","name":"Sam"}]
  

Я был бы признателен, если вы, ребята, сможете мне помочь.

Комментарии:

1. «Я хочу использовать только пакет «re» и встроенные функции для предварительной обработки этих данных» Почему? Использование re для этого звучит как ужасная идея, а встроенные функции означали бы использование eval для разбора списка, что не менее ужасно. Вместо этого я бы настоятельно рекомендовал использовать json для анализа списка, а затем dict для поиска дубликатов.

2. Использовать re было бы глупо. Вы должны использовать json.loads

3. Почему запись с идентификатором ‘1111’ не находится в требуемом выводе? Как я понимаю, дубликаты должны быть удалены. Или следует удалить словари, в которых есть дубликаты?

4. Спасибо за ваш отзыв. Я только что обновил требуемый вывод.

Ответ №1:

Использование re для этого звучит как ужасная идея, и только встроенные функции означали бы использование eval для разбора списка, что не менее ужасно.

Вместо этого я бы предложил использовать json для анализа строки, затем collections.Counter для поиска дубликатов и, наконец, простое понимание списка для повторного создания уникальных словарей из ключей (созданных для хэширования) в счетчике.

 >>> import json, collections
>>> lst = json.loads(string)["information"]
>>> c = collections.Counter(frozenset(d.items()) for d in lst)
>>> [dict(x) for x in c if c[x] == 1]
[{'ID': '2222', 'name': 'Jane', 'Age': '31'},
 {'Age': '28', 'name': 'Sam', 'ID': '3333'}]
  

Если вы действительно действительно хотите использовать just re , вы можете попробовать следующее: 1. используйте регулярное выражение для search [...] списка; б) используйте другое регулярное выражение для findall {...} групп в предыдущем совпадении; (iii) во всех этих частях используйте еще одно регулярное выражение, чтобы получить все '...': '...' биты; наконец, используйте их для воссоздания словарей и действуйте, как указано выше. (Однако, на самом деле не имеет никакого смысла использовать regex для разбора структуры, подобной этой.)

Ответ №2:

Вы могли бы использовать pandas, если хотите. Позвольте еще раз сказать, что вам, вероятно, не следует использовать eval, поскольку это может быть опасно.

 import ast
import pandas as pd

pd.DataFrame(ast.literal_eval(string)['information']).drop_duplicates(keep=False).to_dict('records')
  

Вывод

 [{'ID': '2222', 'name': 'Jane', 'Age': '31'}, {'ID': '3333', 'name': 'Sam', 'Age': '28'}]
  

Ответ №3:

Один из способов — использовать literal_eval из ast для безопасной оценки строки, а затем использовать set comprehension для uniquefy словари, преобразованные в кортежи, а затем преобразовать эти уникальные кортежи обратно в словари:

 import ast

d = ast.literal_eval(string)

uniq = {tuple(sorted(record.items())) for record in d['information']}

result = [dict(item) for item in uniq]

# result -> [{'Age': '28', 'ID': '3333', 'name': 'Sam'}, {'Age': '31', 'ID': '2222', 'name': 'Jane'}, {'Age': '20', 'ID': '1111', 'name': 'Smith'}]
  

Ответ №4:

Вы можете попробовать это

 string = """{"information": [{"ID":"1111","name":"Smith","Age":"20"},       
             {"Age":"31","name":"Jane","ID":"2222"},
             {"ID":"1111","name":"Smith","Age":"20"},
             {"ID":"1111","Age":"20","name":"Smith"},
             {"ID":"3333","Age":"28","name":"Sam"}]}"""
exec('d=' string)
l = []
for r in d['information']:
    if r not in l:
        l.append(r)
print(l)