Как предотвратить дублирование UUID в повторяющихся текстах (в списке dicts) в python?

#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. Это действительно полезно. Спасибо!