如何根据键值“对”展开python列表字典?
我在使用Python3.x列表字典时遇到了一个算法问题,不过也许另一种数据结构更合适 假设我有以下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
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谢谢,很高兴我帮了你,