Python 检查字典中的键是否也作为值存在,如果是,则合并它们?

Python 检查字典中的键是否也作为值存在,如果是,则合并它们?,python,dictionary,Python,Dictionary,我正在尝试使用Python字典从Excel电子表格中创建分类结构。每个实体都有几个子实体,我想将其表示为一个嵌套的Python字典 我的电子表格如下所示: Entity Includes Account Customer Account Account Corporate Account Account Account Balance Account Balance Exposure {'

我正在尝试使用Python字典从Excel电子表格中创建分类结构。每个实体都有几个子实体,我想将其表示为一个嵌套的Python字典

我的电子表格如下所示:

Entity              Includes
Account             Customer Account
Account             Corporate Account
Account             Account Balance
Account Balance     Exposure
{'Account': ['Customer Account',
             'Corporate Account',
             'Account Balance'],
 'Account Balance': ['Exposure']}
诸如此类

我将文件加载到数据框中,然后通过Pandas的groupby split apply创建字典:

df = pd.read_excel('taxonomy_file.xlsx')

groupby = dict(df.groupby('Entity')['Includes'].apply(list))
生成的词典如下所示:

Entity              Includes
Account             Customer Account
Account             Corporate Account
Account             Account Balance
Account Balance     Exposure
{'Account': ['Customer Account',
             'Corporate Account',
             'Account Balance'],
 'Account Balance': ['Exposure']}
我想要的结果是写一些东西来检测“账户余额”既是一个键又是一个值,并将作为一个值的“账户余额”转换为同时作为“暴露”的值和键的值:

{'Account': ['Customer Account',
             'Corporate Account',
             {'Account Balance': 'Exposure'}]
归根结底,我需要处理的术语并不多,但我更希望不要手动处理。我尝试过做如下的事情,只是为了测试是否可以在字典的不同部分同时检测键和值:

for k, v in groupby.items():
    if k in v:
        print(k)

但是没有运气,因为它只在每个键都存在于该键的值列表中时才进行搜索。我主要是在寻找关于如何解决这个问题的任何指针或想法,或者我的想法是错误的。

我假设您的文件是树结构的转换(但它可能是任何有向图)。第一个想法是区分引用和根:根是一个从来不是值的键,而引用是一个也是值的键:

all_values = set(x for xs in d.values() for x in xs)
refs = all_values & set(d.keys())
我们还需要一个函数,该函数在refs中搜索一个键,如果找到该键,则返回一个新的dict:

def resolve_ref(key):
    if key in refs:
        return {key: [resolve_ref(x) for x in d[key]]}
    else:
        return key
这个函数显然是递归的,因为我们需要解析refs,refs的refs。。。。最后,值中没有ref

最后一部分是创建仅具有非ref键的dict,并解析值中的所有ref:

{k: [resolve_ref(x) for x in vs] for k, vs in d.items() if k not in refs}
让我们将这些块放在一起,并尝试一个更复杂的示例:

def consolidate(d):
    all_values = set(x for xs in d.values() for x in xs)
    refs = all_values & set(d.keys())

    def resolve_ref(key):
        if key in refs:
            return {key: [resolve_ref(x) for x in d[key]]}
        else:
            return key

    return {k: [resolve_ref(x) for x in vs] for k, vs in d.items() if k not in refs}
例如:

d = {'Account': ['Customer Account',
             'Corporate Account',
             'Account Balance'],
    'Account Balance': ['Exposure'],
    'Exposure': ['Foo', 'Bar']} 

print(consolidate(d))
# {'Account': ['Customer Account', 'Corporate Account', {'Account Balance': [{'Exposure': ['Foo', 'Bar']}]}]}
注意:循环将被删除,因为如果有循环的根,它也将是一个值,因此是一个ref而不是根

d = {'Foo': ['Bar'],
    'Bar': ['Baz'],
    'Baz': ['Foo']}
print(consolidate(d))
# {}

一个问题是:如果
账户余额
在第二列的另一行中也有EIXST,您将如何处理它?在每个键值对中复制它们?太棒了。这对我的用例非常有效。谢谢你的帮助!