Удалите повторяющееся значение во вложенном словаре - PullRequest
0 голосов
/ 18 июня 2020

У меня есть вложенный словарь d1

d1={'Hiraki': {'Hiraki_2': ['KANG_785','KANG_785','KANG_762']}, 'LakeTaupo': {'LakeTaupo_2': ['KANG_785', 'KANG_785', 'KANG_785', 'KANG_751']}}

Я хотел бы удалить повторяющиеся значения для каждого ключа. Результат после удаления повторяющихся значений должен быть:

d1={'Hiraki': {'Hiraki_2': ['KANG_785','KANG_762']}, 'LakeTaupo': {'LakeTaupo_2': ['KANG_785', 'KANG_751']}}

Я не знаю, как это закодировать в python. Пожалуйста, помогите мне.

Ответы [ 5 ]

2 голосов
/ 18 июня 2020

Вы можете использовать ту же стратегию, что описана в этом ответе:

Преобразование смешанного вложенного словаря в список

, но для случая, когда isinstance(d, list), вернуть list(set(d)) (что удалит повторяющиеся записи) вместо d.

Например:

def dedupe_lists(d: dict) -> dict:
    if isinstance(d, list):
        return list(set(d))
    if isinstance(d, dict):
        return {k: dedupe_lists(v) for k, v in d.items()}
    return d
1 голос
/ 18 июня 2020

Вот рекурсивное решение:

Это изменит списки inplace

d1={'Hiraki': {'Hiraki_2': ['KANG_785','KANG_785','KANG_762']}, 'LakeTaupo': {'LakeTaupo_2': ['KANG_785', 'KANG_785', 'KANG_785', 'KANG_751']}}

# Deals with the tuples
def recurse_tuple(my_tup):
    for i, v in enumerate(my_tup):
        if isinstance(v, dict): my_tup[i] = recurse_dict(v)
    return my_tup

# Deals with the dictionaries and lists
def recurse_dict(my_dict):
    for k, v in my_dict.items():
        if isinstance(v, dict): my_dict[k] = recurse_dict(v)
        if isinstance(v, tuple): my_dict[k] = recurse_tuple(v)
        if isinstance(v, list): my_dict[k] = set(v)
    return my_dict

print(recurse_dict(d1))

#Output
{'Hiraki': {'Hiraki_2': {'KANG_762', 'KANG_785'}}, 'LakeTaupo': {'LakeTaupo_2': {'KANG_785', 'KANG_751'}}}

ПРИМЕЧАНИЕ: @Samwise избил меня очень аккуратным рекурсивная функция.

1 голос
/ 18 июня 2020

Вы можете использовать set () для удаления дубликатов.

d1={'Hiraki': {'Hiraki_2': ['KANG_785','KANG_785','KANG_762']}, 'LakeTaupo': {'LakeTaupo_2': ['KANG_785', 'KANG_785', 'KANG_785', 'KANG_751']}}

d2 ={key1: {key2: list(set(val2)) for key2, val2 in val1.items()} for key1, val1 in 
d1.items()}

print(d2)

Вывод:

{'Hiraki': {'Hiraki_2': ['KANG_785', 'KANG_762']}, 'LakeTaupo': {'LakeTaupo_2': ['KANG_785', 'KANG_751']}}
1 голос
/ 18 июня 2020

По сути, если вы хотите удалить повторяющиеся значения в sequence, вы конвертируете его в set, а затем обратно.

>>> data = ['KANG_785','KANG_785','KANG_762']
>>> data = list(set(data))
>>> data
['KANG_762', 'KANG_785']

Обратите внимание, что это не поддерживает порядок.

Также внимательно подумайте, действительно ли вам нужен list или нет; set по-прежнему итеративен, поэтому, если вы хотите поддерживать уникальность все время, подумайте о том, чтобы сохранить данные как set и конвертировать в list только при необходимости.

>>> data = ['KANG_785','KANG_785','KANG_762']
>>> data = set(data)
>>> data
{'KANG_762', 'KANG_785'}
>>> for i in data:
...     print(i)
...     
KANG_762
KANG_785
>>> type(data)
<class 'set'>
1 голос
/ 18 июня 2020

Вы можете попробовать:

d1={'Hiraki': {'Hiraki_2': ['KANG_785','KANG_785','KANG_762']}, 'LakeTaupo': {'LakeTaupo_2': ['KANG_785', 'KANG_785', 'KANG_785', 'KANG_751']}}

output = {}
for key, val in d1.items():
    for key1, val1 in val.items():
        output[key] = {
            key1: list(set(val1))
        }
print(output)

Вывод:

{'Hiraki': {'Hiraki_2': ['KANG_785', 'KANG_762']}, 'LakeTaupo': {'LakeTaupo_2': ['KANG_785', 'KANG_751']}}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...