#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.loads3. Почему запись с идентификатором ‘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)