我使用列表的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关联,依此类推
是否有一种方法可以像这样“展开”字典?
如何将其扩展为更大的字典,其中包含数百万个整数的较大列表?
也许其他数据结构在这里会更有效,尤其是对于更大的列表?
编辑:鉴于我正在使用的实际字典的大小(不是上面发布的字典的大小),该解决方案应尽可能提高内存/性能效率。
答案 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]}