【问题标题】:How to unfold a python dictionary of lists based on key-value "pairs"?如何展开基于键值“对”的python列表字典?
【发布时间】:2018-09-02 02:24:23
【问题描述】:

我有一个使用 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 相关联,等等。

有没有办法像这样“展开”字典?

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

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

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

【问题讨论】:

  • 这取决于您的值范围,但您可以使用稀疏矩阵(例如来自scipy)将关联存储在邻接矩阵中,以提高效率。

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


【解决方案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})

【讨论】:

  • 技术上一个两行来获得请求的输出。但是很好。
  • 我相信这是性能最高的选项,基于timeit
  • @ShanZhengYang 谢谢,很高兴我的帮助,?
【解决方案2】:

以下会做:

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

【讨论】:

  • 双 for 循环让我觉得这对于大型字典来说效率非常低,对吧?
  • 这是必要的,因为您有 n 个数字,每个数字都映射到 i(n) 个数字,因此有必要至少取 n x i(n) 次迭代的总和来构建反向映射。跨度>
【解决方案3】:

一种方法是使用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]}

【讨论】:

    【解决方案4】:

    您基本上是在尝试存储关系。关于这个有一个完整的领域——它们存储在关系数据库中,其中包含。在 Python 中,将其作为 2-lists 的列表来执行会更自然——或者,由于您的关系是对称的并且顺序无关紧要,因此可以使用 2-sets 的列表。一个更好的解决方案是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]}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-20
      • 2020-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-01
      • 2021-09-07
      相关资源
      最近更新 更多