如何根据键值“对”展开python列表字典?

如何根据键值“对”展开python列表字典?,python,python-3.x,dictionary,key-value,Python,Python 3.x,Dictionary,Key Value,我在使用Python3.x列表字典时遇到了一个算法问题,不过也许另一种数据结构更合适 假设我有以下Python字典: dict1 = {1:[4, 12, 22], 2:[4, 5, 13, 23], 3:[7, 15, 25]} 与值[4,12,22]关联的键1表示1与4关联。1还与12关联,1与22关联。此外,2与4关联,2与5关联,2与13关联,1与23关联,以此类推 我的问题是,对于这个小例子,我如何展开这个字典,使值列表的每个元素都编码这个关联 也就是说,最终结果应该是: inten

我在使用Python3.x列表字典时遇到了一个算法问题,不过也许另一种数据结构更合适

假设我有以下Python字典:

dict1 = {1:[4, 12, 22], 2:[4, 5, 13, 23], 3:[7, 15, 25]}
与值[4,12,22]关联的键1表示1与4关联。1还与12关联,1与22关联。此外,2与4关联,2与5关联,2与13关联,1与23关联,以此类推

我的问题是,对于这个小例子,我如何展开这个字典,使值列表的每个元素都编码这个关联

也就是说,最终结果应该是:

intended_dict = {1:[4, 12, 22], 2:[4, 5, 13, 23], 3:[7, 15, 25], 
                     4:[1, 2], 5:[2], 12:[1], 13:[2], 15:[3], 22:[1], 23:[2], 25:[3]}
因为4与1关联,4与2关联,5与2关联,以此类推

有没有像这样展开词典的方法

这将如何扩展到一个包含数百万个整数的更大列表的大得多的字典

也许另一种数据结构在这里会更有效,尤其是对于更大的列表

编辑:考虑到我正在使用的实际词典的大小,而不是上面发布的词典,解决方案应尽可能提高内存/性能效率。

以下操作即可:

intended_dict = dict1.copy()
for k, v in dict1.items():
    for i in v:
        intended_dict.setdefault(i, []).append(k)
以下步骤可以:

intended_dict = dict1.copy()
for k, v in dict1.items():
    for i in v:
        intended_dict.setdefault(i, []).append(k)
一种方法是使用collections.defaultdict

一种方法是使用collections.defaultdict

简单一行:

newdict={v:[i for i in dict1.keys() if v in dict1[i]] for k,v in dict1.items() for v in v}
print(newdict)
输出:

{4: [1, 2], 12: [1], 22: [1], 5: [2], 13: [2], 23: [2], 7: [3], 15: [3], 25: [3]}
要合并它们,请执行以下操作:

print({**dict1,**newdict})
简单一行:

newdict={v:[i for i in dict1.keys() if v in dict1[i]] for k,v in dict1.items() for v in v}
print(newdict)
输出:

{4: [1, 2], 12: [1], 22: [1], 5: [2], 13: [2], 23: [2], 7: [3], 15: [3], 25: [3]}
要合并它们,请执行以下操作:

print({**dict1,**newdict})

你基本上是想储存关系。这方面有一个完整的领域——它们存储在包含表的关系数据库中。在Python中,更自然的做法是将其作为一个由2个列表组成的列表,或者,由于您的关系是对称的,并且顺序并不重要,所以将其作为一个由2个集合组成的列表。不过,一个更好的解决方案是pandas,它是用Python编写表的规范包

目前,这里介绍如何将原始对象转化为熊猫对象,然后将其转化为包含对称性的固定对象

import pandas as pd

dict1 = {1:[4, 12, 22], 2:[4, 5, 13, 23], 3:[7, 15, 25]}

relations = pd.DataFrame(
    [[key, value] for key, values in dict1.items() for value in values]
)

print(relations)

Out:
   0   1
0  1   4
1  1  12
2  1  22
3  2   4
4  2   5
5  2  13
6  2  23
7  3   7
8  3  15
9  3  25

result = {
    **{key: list(values) for key, values in relations.groupby(0)[1]},
    **{key: list(values) for key, values in relations.groupby(1)[0]}
}

print(result)

Out:
{1: [4, 12, 22],
 2: [4, 5, 13, 23],
 3: [7, 15, 25],
 4: [1, 2],
 5: [2],
 7: [3],
 12: [1],
 13: [2],
 15: [3],
 22: [1],
 23: [2],
 25: [3]}

你基本上是想储存关系。这方面有一个完整的领域——它们存储在包含表的关系数据库中。在Python中,更自然的做法是将其作为一个由2个列表组成的列表,或者,由于您的关系是对称的,并且顺序并不重要,所以将其作为一个由2个集合组成的列表。不过,一个更好的解决方案是pandas,它是用Python编写表的规范包

目前,这里介绍如何将原始对象转化为熊猫对象,然后将其转化为包含对称性的固定对象

import pandas as pd

dict1 = {1:[4, 12, 22], 2:[4, 5, 13, 23], 3:[7, 15, 25]}

relations = pd.DataFrame(
    [[key, value] for key, values in dict1.items() for value in values]
)

print(relations)

Out:
   0   1
0  1   4
1  1  12
2  1  22
3  2   4
4  2   5
5  2  13
6  2  23
7  3   7
8  3  15
9  3  25

result = {
    **{key: list(values) for key, values in relations.groupby(0)[1]},
    **{key: list(values) for key, values in relations.groupby(1)[0]}
}

print(result)

Out:
{1: [4, 12, 22],
 2: [4, 5, 13, 23],
 3: [7, 15, 25],
 4: [1, 2],
 5: [2],
 7: [3],
 12: [1],
 13: [2],
 15: [3],
 22: [1],
 23: [2],
 25: [3]}

double for循环让我觉得这对于大型字典来说效率很低,对吧?这是必要的,因为你有n个数字,每个数字都映射到in数字,所以有必要在迭代中取最小的nx之和来构建反向映射。double for循环让我觉得这对于大型字典来说是非常低效的,对吧?这是必要的,因为你有n个数字,每个数字都映射到in数字,因此,有必要在迭代中取nx之和的最小值来构建反向映射。这取决于您的值边界,但您可以使用稀疏矩阵(例如,从)将关联存储在邻接矩阵中,以提高效率。这取决于您的值边界,但您可以将关联存储在邻接矩阵中,使用稀疏矩阵,例如from,以获得更高的效率。从技术上讲,使用两行程序来获得请求的输出。但是很好。我相信这是最有效的选择,基于timeit@ShanZhengYang谢谢,很高兴我帮了忙,从技术上讲,是一个两行程序来获得要求的输出。但是很好。我相信这是最有效的选择,基于timeit@ShanZhengYang谢谢,很高兴我帮了你,