#python #json #nested #duplicates #uuid
#python #json #вложенный #дубликаты #uuid
Вопрос:
Я должен фильтровать тексты, которые я обрабатываю, проверяя, отображаются ли имена людей в тексте ( texts
). Если они появляются, тексты добавляются как вложенный список словарей к существующему списку словарей, содержащих имена людей ( people
). Однако, поскольку в некоторых текстах появляется более одного имени пользователя, дочерний документ, содержащий тексты, будет повторен и добавлен снова. В результате дочерний документ не содержит уникального идентификатора, и этот уникальный идентификатор очень важен, независимо от повторяющихся текстов.
Есть ли более разумный способ добавления уникального идентификатора, даже если тексты повторяются?
Мой код:
import uuid
people = [{'id': 1,
'name': 'Bob',
'type': 'person',
'_childDocuments_': [{'text': 'text_replace'}]},
{'id': 2,
'name': 'Kate',
'type': 'person',
'_childDocuments_': [{'text': 'text_replace'}]},
{'id': 3,
'name': 'Joe',
'type': 'person',
'_childDocuments_': [{'text': 'text_replace'}]}]
texts = ['this text has the name Bob and Kate',
'this text has the name Kate only ']
for text in texts:
childDoc={'id': str(uuid.uuid1()), #the id will duplicate when files are repeated
'text': text}
for person in people:
if person['name'] in childDoc['text']:
person['_childDocuments_'].append(childDoc)
Текущий вывод:
[{'id': 1,
'name': 'Bob',
'type': 'person',
'_childDocuments_': [{'text': 'text_replace'},
{'id': '7752597f-410f-11eb-9341-9cb6d0897972', #duplicate ID here
'text': 'this text has the name Bob and Kate'}]},
{'id': 2,
'name': 'Kate',
'type': 'person',
'_childDocuments_': [{'text': 'text_replace'},
{'id': '7752597f-410f-11eb-9341-9cb6d0897972', #duplicate ID here
'text': 'this text has the name Bob and Kate'},
{'id': '77525980-410f-11eb-b667-9cb6d0897972',
'text': 'this text has the name Kate only '}]},
{'id': 3,
'name': 'Joe',
'type': 'person',
'_childDocuments_': [{'text': 'text_replace'}]}]
Как вы можете видеть в текущем выводе, идентификатор текста 'this text has the name Bob and Kate'
имеет один и тот же идентификатор: '7752597f-410f-11eb-9341-9cb6d0897972'
, потому что он добавляется дважды. Но я бы хотел, чтобы каждый идентификатор был другим.
Желаемый результат:
То же, что и текущий вывод, за исключением того, что мы хотим, чтобы каждый идентификатор отличался для каждого добавленного текста, даже если эти тексты одинаковые / дубликаты.
Комментарии:
1. В настоящее время вы генерируете идентификатор только один раз и повторно используете его.
Ответ №1:
Переместите генерацию UUID во внутренний цикл:
for text in texts:
for person in people:
if person['name'] in text:
childDoc={'id': str(uuid.uuid1()),
'text': text}
person['_childDocuments_'].append(childDoc)
На самом деле это не гарантирует, что UUID является уникальным. Для этого вам нужно иметь набор используемых UUID, и при создании нового вы проверяете, используется ли он уже, и если он есть, вы создаете другой. И протестируйте это и повторяйте, пока не исчерпаете пространство UUID или не найдете неиспользуемый UUID.
Вероятность создания дубликатов составляет 1 из 2 ** 61. Я не могу принять столкновения, поскольку они приводят к потере данных. Поэтому, когда я использую UUID, у меня есть цикл вокруг генератора, который выглядит следующим образом:
used = set()
while True:
identifier = str(uuid.uuid1())
if identifier not in used:
used.add(identifier)
break
Используемый набор фактически сохраняется постоянно. Мне не нравится этот код, хотя у меня есть программа, которая использует его, поскольку он попадает в бесконечный цикл, когда не может найти неиспользуемый UUID.
Некоторые базы данных документов предоставляют автоматическое назначение UUID, и они делают это для вас внутренне, чтобы гарантировать, что в данном экземпляре базы данных никогда не будет двух документов с одинаковым UUID.
Комментарии:
1. Это действительно полезно. Спасибо!