如何展开基于键值 "pairs" 的 python 列表字典?
How to unfold a python dictionary of lists based on key-value "pairs"?
我在使用 Python3.x 列表字典时遇到算法问题,但也许另一种数据结构更合适。
假设我有以下 Python 字典:
dict1 = {1:[4, 12, 22], 2:[4, 5, 13, 23], 3:[7, 15, 25]}
键1
关联值[4, 12, 22]
表示1是"associated with"4。1也关联12,1关联22。另外,2关联与 4 相关联,2 与 5 相关联,2 与 13 相关联,1 与 23 相关联,等等
我的问题是,对于这个小例子,我如何 "unfold" 这个字典使得值列表的每个元素都编码这个 "association"?
即最终结果应该是:
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 关联,等等
有没有这样"unfold"字典的方法?
这将如何扩展到包含包含数百万整数的更大列表的更大字典?
也许另一种数据结构在这里更有效,尤其是对于更大的列表?
编辑:考虑到我正在使用的实际字典的大小(不是上面发布的那个),解决方案应该尽可能 memory-/performance-efficient。
执行以下操作:
intended_dict = dict1.copy()
for k, v in dict1.items():
for i in v:
intended_dict.setdefault(i, []).append(k)
一种方法是使用 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]}
简单的一行:
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.
中制作表格的规范包
暂时这里是如何将你的原始事物变成一个 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]}
我在使用 Python3.x 列表字典时遇到算法问题,但也许另一种数据结构更合适。
假设我有以下 Python 字典:
dict1 = {1:[4, 12, 22], 2:[4, 5, 13, 23], 3:[7, 15, 25]}
键1
关联值[4, 12, 22]
表示1是"associated with"4。1也关联12,1关联22。另外,2关联与 4 相关联,2 与 5 相关联,2 与 13 相关联,1 与 23 相关联,等等
我的问题是,对于这个小例子,我如何 "unfold" 这个字典使得值列表的每个元素都编码这个 "association"?
即最终结果应该是:
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 关联,等等
有没有这样"unfold"字典的方法?
这将如何扩展到包含包含数百万整数的更大列表的更大字典?
也许另一种数据结构在这里更有效,尤其是对于更大的列表?
编辑:考虑到我正在使用的实际字典的大小(不是上面发布的那个),解决方案应该尽可能 memory-/performance-efficient。
执行以下操作:
intended_dict = dict1.copy()
for k, v in dict1.items():
for i in v:
intended_dict.setdefault(i, []).append(k)
一种方法是使用 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]}
简单的一行:
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.
暂时这里是如何将你的原始事物变成一个 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]}