Как удалить повторяющиеся записи из словаря в словаре?

1

Цель моего кода заключается в том, что в файле, который я разбираю, должно появиться не более одного человека с тем же именем и датой рождения.

Вот мой словарь в словаре, который называется ind:

{I19: {'BIRT': '13 FEB 1981', 'sex': 'M', 'id': 'I19', 'family': 'F23', 'name': 'Dick /Smith/'}}
{I32: {'BIRT': '27 MAY 1991', 'sex': 'M', 'id': 'I32', 'family': 'F16', 'name': 'Nick /Tary/'}}
{I30: {'BIRT': '3 SEP 1993', 'sex': 'F', 'id': 'I30', 'family': 'F16', 'name': 'Mary /Test/'}}
{I26: {'BIRT': '2 JUN 1983', 'sex': 'F', 'id': 'I26', 'family': 'F23', 'name': 'Jane /Smith/'}}
{I01: {'name': 'Joe /Smith/', 'family': 'F23', 'BIRT': '15 JUL 1960', 'sex': 'M', 'id': 'I01', 'DEAT': '31 DEC 2013'}}
{I07: {'BIRT': '23 SEP 1960', 'sex': 'F', 'id': 'I07', 'family': 'F23', 'name': 'Jennifer /Smith/'}}
{I19: {'BIRT': '13 FEB 1981', 'sex': 'M', 'id': 'I19', 'family': 'F23', 'name': 'Dick /Smith/'}}

Мой код должен избавиться от одной из записей Дика Смита с тех пор 2.

Вот мой код для этой части (пока не удаляет дубликат):

for individual in ind:
    name1 = ind[individual]['name']
    bdate1 = ind[individual]['BIRT']
    for individual_2 in ind:
        name2 = ind[individual]['name']
        bdate2 = ind[individual]['BIRT']
        if name1 == name2 and bdate1 == bdate2:
            print("{} already exists. Removing duplicate entry.".format(name1))

но это дает мне:

Dick /Smith/ already exists. Removing duplicate entry.
Dick /Smith/ already exists. Removing duplicate entry.
Dick /Smith/ already exists. Removing duplicate entry.
Dick /Smith/ already exists. Removing duplicate entry.
Dick /Smith/ already exists. Removing duplicate entry.
Dick /Smith/ already exists. Removing duplicate entry.
Nick /Tary/ already exists. Removing duplicate entry.
Nick /Tary/ already exists. Removing duplicate entry.
Nick /Tary/ already exists. Removing duplicate entry.
Nick /Tary/ already exists. Removing duplicate entry.
Nick /Tary/ already exists. Removing duplicate entry.
Nick /Tary/ already exists. Removing duplicate entry.
Mary /Test/ already exists. Removing duplicate entry.
Mary /Test/ already exists. Removing duplicate entry.
Mary /Test/ already exists. Removing duplicate entry.
Mary /Test/ already exists. Removing duplicate entry.
Mary /Test/ already exists. Removing duplicate entry.
Mary /Test/ already exists. Removing duplicate entry.
Jane /Smith/ already exists. Removing duplicate entry.
Jane /Smith/ already exists. Removing duplicate entry.
Jane /Smith/ already exists. Removing duplicate entry.
Jane /Smith/ already exists. Removing duplicate entry.
Jane /Smith/ already exists. Removing duplicate entry.
Jane /Smith/ already exists. Removing duplicate entry.
Joe /Smith/ already exists. Removing duplicate entry.
Joe /Smith/ already exists. Removing duplicate entry.
Joe /Smith/ already exists. Removing duplicate entry.
Joe /Smith/ already exists. Removing duplicate entry.
Joe /Smith/ already exists. Removing duplicate entry.
Joe /Smith/ already exists. Removing duplicate entry.
Jennifer /Smith/ already exists. Removing duplicate entry.
Jennifer /Smith/ already exists. Removing duplicate entry.
Jennifer /Smith/ already exists. Removing duplicate entry.
Jennifer /Smith/ already exists. Removing duplicate entry.
Jennifer /Smith/ already exists. Removing duplicate entry.
Jennifer /Smith/ already exists. Removing duplicate entry.

Извиняюсь, если вопрос кажется легким - я новичок в этом. Был бы признателен за любую проницательность.

Теги:
python-3.x

3 ответа

1
Лучший ответ
list_of_dict = [{'I19': {'BIRT': '13 FEB 1981', 'sex': 'M', 'id': 'I19', 'family': 'F23', 'name': 'Dick /Smith/'}},
     {'I32': {'BIRT': '27 MAY 1991', 'sex': 'M', 'id': 'I32', 'family': 'F16', 'name': 'Nick /Tary/'}}
,{'I30': {'BIRT': '3 SEP 1993', 'sex': 'F', 'id': 'I30', 'family': 'F16', 'name': 'Mary /Test/'}}
,{'I26': {'BIRT': '2 JUN 1983', 'sex': 'F', 'id': 'I26', 'family': 'F23', 'name': 'Jane /Smith/'}}
,{'I01': {'name': 'Joe /Smith/', 'family': 'F23', 'BIRT': '15 JUL 1960', 'sex': 'M', 'id': 'I01', 'DEAT': '31 DEC 2013'}}
,{'I07': {'BIRT': '23 SEP 1960', 'sex': 'F', 'id': 'I07', 'family': 'F23', 'name': 'Jennifer /Smith/'}}
,{'I19': {'BIRT': '13 FEB 1981', 'sex': 'M', 'id': 'I19', 'family': 'F23', 'name': 'Dick /Smith/'}}]

new_d = {v['name'] : {k : v} for d in list_of_dict for k,v in d.items()}

for v in new_d.values():
    print(v)

выход

{'I19': {'BIRT': '13 FEB 1981', 'sex': 'M', 'id': 'I19', 'family': 'F23', 'name': 'Dick /Smith/'}}
{'I32': {'BIRT': '27 MAY 1991', 'sex': 'M', 'id': 'I32', 'family': 'F16', 'name': 'Nick /Tary/'}}
{'I30': {'BIRT': '3 SEP 1993', 'sex': 'F', 'id': 'I30', 'family': 'F16', 'name': 'Mary /Test/'}}
{'I26': {'BIRT': '2 JUN 1983', 'sex': 'F', 'id': 'I26', 'family': 'F23', 'name': 'Jane /Smith/'}}
{'I01': {'name': 'Joe /Smith/', 'family': 'F23', 'BIRT': '15 JUL 1960', 'sex': 'M', 'id': 'I01', 'DEAT': '31 DEC 2013'}}
{'I07': {'BIRT': '23 SEP 1960', 'sex': 'F', 'id': 'I07', 'family': 'F23', 'name': 'Jennifer /Smith/'}}

Обратите внимание, что в этом случае только имя сохраняется в случае dup

  • 0
    обновил мой ответ, пожалуйста, просмотрите, прежде чем пометить его как правильный ...
1

Один из способов заключается в использовании itertools рецепт unique_everseen, доступный в стандартной библиотеке. Если у вас есть доступ к третьей стороне библиотеки toolz, вы можете использовать toolz.unique.

Мы определяем функцию, по которой мы определяем, является ли словарь уникальным. В этом случае нам нужно только проверить name ключа каждого словаря.

Используя этот метод, первое вхождение сохраняется только для каждого уникального имени.

from toolz import unique

res = list(unique(ind, lambda x: next(iter(x.items()))[1]['name']))

Настроить

ind = [{'I19': {'BIRT': '13 FEB 1981', 'sex': 'M', 'id': 'I19', 'family': 'F23', 'name': 'Dick /Smith/'}},
       {'I32': {'BIRT': '27 MAY 1991', 'sex': 'M', 'id': 'I32', 'family': 'F16', 'name': 'Nick /Tary/'}},
       {'I30': {'BIRT': '3 SEP 1993', 'sex': 'F', 'id': 'I30', 'family': 'F16', 'name': 'Mary /Test/'}},
       {'I26': {'BIRT': '2 JUN 1983', 'sex': 'F', 'id': 'I26', 'family': 'F23', 'name': 'Jane /Smith/'}},
       {'I01': {'name': 'Joe /Smith/', 'family': 'F23', 'BIRT': '15 JUL 1960', 'sex': 'M', 'id': 'I01', 'DEAT': '31 DEC 2013'}},
       {'I07': {'BIRT': '23 SEP 1960', 'sex': 'F', 'id': 'I07', 'family': 'F23', 'name': 'Jennifer /Smith/'}},
       {'I19': {'BIRT': '13 FEB 1981', 'sex': 'M', 'id': 'I19', 'family': 'F23', 'name': 'Dick /Smith/'}}]

Результат

[{'I19': {'BIRT': '13 FEB 1981', 'sex': 'M', 'id': 'I19', 'family': 'F23', 'name': 'Dick /Smith/'}},
 {'I32': {'BIRT': '27 MAY 1991', 'sex': 'M', 'id': 'I32', 'family': 'F16', 'name': 'Nick /Tary/'}},
 {'I30': {'BIRT': '3 SEP 1993', 'sex': 'F', 'id': 'I30', 'family': 'F16', 'name': 'Mary /Test/'}},
 {'I26': {'BIRT': '2 JUN 1983', 'sex': 'F', 'id': 'I26', 'family': 'F23', 'name': 'Jane /Smith/'}},
 {'I01': {'name': 'Joe /Smith/', 'family': 'F23', 'BIRT': '15 JUL 1960', 'sex': 'M', 'id': 'I01', 'DEAT': '31 DEC 2013'}},
 {'I07': {'BIRT': '23 SEP 1960', 'sex': 'F', 'id': 'I07', 'family': 'F23', 'name': 'Jennifer /Smith/'}}]
0

Если ваш ввод уже является полным словарем, дубликаты будут удалены, так как дважды появляется 'I19'. Однако, если ваши данные представляют собой список словарей, вы можете использовать itertools.groupby:

import itertools
def depth_key(x):
  [[_, c]] = list(x.items())
  return [c['name'], c['BIRT']]

d = [{'I19': {'BIRT': '13 FEB 1981', 'sex': 'M', 'id': 'I19', 'family': 'F23', 'name': 'Dick /Smith/'}}, {'I32': {'BIRT': '27 MAY 1991', 'sex': 'M', 'id': 'I32', 'family': 'F16', 'name': 'Nick /Tary/'}}, {'I30': {'BIRT': '3 SEP 1993', 'sex': 'F', 'id': 'I30', 'family': 'F16', 'name': 'Mary /Test/'}}, {'I26': {'BIRT': '2 JUN 1983', 'sex': 'F', 'id': 'I26', 'family': 'F23', 'name': 'Jane /Smith/'}}, {'I01': {'name': 'Joe /Smith/', 'family': 'F23', 'BIRT': '15 JUL 1960', 'sex': 'M', 'id': 'I01', 'DEAT': '31 DEC 2013'}}, {'I07': {'BIRT': '23 SEP 1960', 'sex': 'F', 'id': 'I07', 'family': 'F23', 'name': 'Jennifer /Smith/'}}, {'I19': {'BIRT': '13 FEB 1981', 'sex': 'M', 'id': 'I19', 'family': 'F23', 'name': 'Dick /Smith/'}}]
new_d = [[a, list(b)] for a, b in itertools.groupby(sorted(d, key=depth_key), key=depth_key)]
final_d = [b for _, [b, *c] in new_d]

Выход:

[{'I19': {'BIRT': '13 FEB 1981', 'sex': 'M', 'id': 'I19', 'family': 'F23', 'name': 'Dick /Smith/'}}, {'I26': {'BIRT': '2 JUN 1983', 'sex': 'F', 'id': 'I26', 'family': 'F23', 'name': 'Jane /Smith/'}}, {'I07': {'BIRT': '23 SEP 1960', 'sex': 'F', 'id': 'I07', 'family': 'F23', 'name': 'Jennifer /Smith/'}}, {'I01': {'name': 'Joe /Smith/', 'family': 'F23', 'BIRT': '15 JUL 1960', 'sex': 'M', 'id': 'I01', 'DEAT': '31 DEC 2013'}}, {'I30': {'BIRT': '3 SEP 1993', 'sex': 'F', 'id': 'I30', 'family': 'F16', 'name': 'Mary /Test/'}}, {'I32': {'BIRT': '27 MAY 1991', 'sex': 'M', 'id': 'I32', 'family': 'F16', 'name': 'Nick /Tary/'}}]

Ещё вопросы

Сообщество Overcoder
Наверх
Меню