如何展开基于键值“对”的列表的python字典?

时间:2018-09-02 02:24:23

标签: python python-3.x dictionary key-value

我使用列表的Python3.x字典遇到算法问题,尽管也许其他数据结构更合适。

假设我有以下Python词典:

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

与值1关联的键[4, 12, 22]表示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关联,依此类推

是否有一种方法可以像这样“展开”字典?

如何将其扩展为更大的字典,其中包含数百万个整数的较大列表?

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

编辑:鉴于我正在使用的实际字典的大小(不是上面发布的字典的大小),该解决方案应尽可能提高内存/性能效率。

4 个答案:

答案 0 :(得分:1)

将执行以下操作:

intended_dict = dict1.copy()
for k, v in dict1.items():
    for i in v:
        intended_dict.setdefault(i, []).append(k)

答案 1 :(得分:1)

一种方法是使用collections.defaultdict

from collections import defaultdict
dict1 = {1:[4, 12, 22], 2:[4, 5, 13, 23], 3:[7, 15, 25]}
d_dict = defaultdict(list)

for k,l in dict1.items():
    for v in l:
        d_dict[v].append(k)

intended_dict = {**dict1, **d_dict}
print (intended_dict)
#{1: [4, 12, 22], 2: [4, 5, 13, 23], 3: [7, 15, 25], 4: [1, 2], 12: [1], 22: [1], 5: [2], 13: [2], 23: [2], 7: [3], 15: [3], 25: [3]}

答案 2 :(得分:1)

一个简单的班轮:

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})

答案 3 :(得分:1)

您基本上是在尝试存储关系。有一个完整的字段-它们存储在关系数据库中,其中包含。在Python中,将其作为2个列表的列表来做会更自然-或者,因为您的关系是对称的且顺序无关紧要,所以将2个列表作为一个列表。不过,还有一个更好的解决方案是pandas,它是在Python中处理表格的规范软件包。

目前,这里是如何将原始内容转换为pandas对象,然后将其转换为包含对称性的固定对象的方法。

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]}