关于合并值的奇怪重复,字典中的键

a weird duplication about merge values, keys in a dictionary

一个问题卡了好几天,谁能指点一下,不胜感激!

描述:

我有一本字典,但我想合并 一些 的值和键,例如:

Input:
initial_dict = {'aa': ['AA'],'bb':['BB'],'BB':['MM'],'cc':['dd'],'dd':['GG','HH','LL']}

Desired output:
goal_dict = {'aa': ['AA'],'bb':['BB','MM'],'cc':['dd','GG','HH','LL']}

也就是说,如果一个key/value已经在它之前的键或值中,那么附加它的value/key 如果这个 value/key 还没有出现(可能不是很清楚,但是请看上面的输入和输出)。

我有以下代码,我认为它们很完美,但我得到了很多重复输出:

dict_head_conj_pair = {'aa': ['AA'],'bb':['BB'],'BB':['MM'],'cc':['dd'],'dd':['GG','HH','LL']}
dict_head_conj_new = {}
print(dict_head_conj_pair)
for a_key in dict_head_conj_pair.keys():
    if dict_head_conj_new:
        if a_key not in dict_head_conj_new.keys():
            for idx_value, new_value_list in enumerate(dict_head_conj_new.copy().values()):
                if a_key in new_value_list:
                    for idx_key, new_key in enumerate(dict_head_conj_new.copy().keys()):
                        if idx_key == idx_value:
                            target_key = new_key
                            for con_0 in range(len(dict_head_conj_pair[a_key])):
                                for new_value_list_1 in dict_head_conj_new.copy().values():
                                    dict_head_conj_new[target_key].append(dict_head_conj_pair[a_key][con_0])
                else:
                    for con_1 in range(len(dict_head_conj_pair[a_key])):
                        if con_1 == 0:
                            dict_head_conj_new.setdefault(a_key, []).append(dict_head_conj_pair[a_key][con_1])
                        else:
                            dict_head_conj_new[a_key].append(dict_head_conj_pair[a_key][con_1])
    else:
        for con_2 in range(len(dict_head_conj_pair[a_key])):
            if con_2==0:
                dict_head_conj_new.setdefault(a_key, []).append(dict_head_conj_pair[a_key][con_2])
            else:
                dict_head_conj_new[a_key].append(dict_head_conj_pair[a_key][con_2])
print("dict_head_conj_new: ",dict_head_conj_new)

当前不需要的输出:

dict_head_conj_new:  {'aa': ['AA'], 'bb': ['BB', 'MM', 'MM', 'MM'], 'BB': ['MM'], 'cc': ['dd', 'dd', 'dd', 'GG', 'GG', 'GG', 'GG', 'GG', 'HH', 'HH', 'HH', 'HH', 'HH', 'LL', 'LL', 'LL', 'LL', 'LL'], 'dd': ['GG', 'HH', 'LL', 'GG', 'HH', 'LL', 'GG', 'HH', 'LL']}

如果有人能看出我哪里错了或提供有关如何获得我想要的结果的提示,我将不胜感激!

谢谢!

如果我没理解错的话,你可以将其建模为图形问题,所以我建议你使用 networkx:

import operator

import networkx as nx

initial_dict = {'aa': ['AA'], 'bb': ['BB'], 'BB': ['MM'], 'cc': ['dd'], 'dd': ['GG', 'HH', 'LL']}
dg = nx.convert.from_dict_of_lists(initial_dict, create_using=nx.DiGraph)

# these are the keys of the dictionaries
seeds = [n for n in dg.nodes if not dg.in_degree(n)]


def descendants(g, source):
    """This function finds all the descendants of source in g sorted by distance to source"""
    desc = sorted(nx.shortest_path_length(g, source).items(), key=operator.itemgetter(1))
    return [d for d, _ in desc if d != source]


# return as dictionary
res = {seed: descendants(dg, seed) for seed in seeds}
print(res)

输出

   {'aa': ['AA'], 'bb': ['BB', 'MM'], 'cc': ['dd', 'HH', 'GG', 'LL']}
some_list = [1, 1, 1, 2, 3]
some_list = list(dict.fromkeys(some_list))

您可以 运行 一个调试器来找出导致问题的原因(这可能很好),但是如果您只需要删除重复项,那么上面的代码可能会起作用。 (用于从列表中删除重复项)。

此外,我觉得图论算法可能与此相关...(例如,在字典中,看看您是否可以使用键访问元素,如果可以,您可以排序“蜘蛛进入”一棵树)

这适用于您的数据,因为它会产生您想要的输出。虽然对于非常大的字典来说可能效率低下(因为需要搜索值),但肯定比你原来的问题少了很多代码。

initial_dict = {'aa': ['AA'],'bb':['BB'],'BB':['MM'],'cc':['dd'],'dd':['GG','HH','LL']}
goal_dict = dict()

def find_value(val):
    for k, v in goal_dict.items():
        if val in v:
            return k

for k, v in initial_dict.items():
    if (_k := find_value(k)):
        goal_dict[_k] += v
    elif not k in goal_dict:
        goal_dict[k] = v