Цель моего кода заключается в том, что в файле, который я разбираю, должно появиться не более одного человека с тем же именем и датой рождения.
Вот мой словарь в словаре, который называется 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.
Извиняюсь, если вопрос кажется легким - я новичок в этом. Был бы признателен за любую проницательность.
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
Один из способов заключается в использовании 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/'}}]
Если ваш ввод уже является полным словарем, дубликаты будут удалены, так как дважды появляется '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/'}}]