如何根据值将 python 字典拆分为多个字典

How to split a python dictionary into multiple dictionaries based on values

我有一本类似的字典:

{'A': [0, 2, 5],
 'B': [1],
 'C': [3, 6, 9],
 'D': [4, 7, 10],
 'E': [8, 11, 13],
 'F': [12]}

我想根据值列表中连续元素的差异将它分成多个字典(比如 2)。例如上图:

dict_2 = {'A': [0, 2],
     'E': [11, 13]}

dict_3 = {'A': [2, 5],
     'C': [3, 6, 9],
     'D': [4, 7, 10],
     'E': [8, 11]}

所以我比较每个列表中的连续值,如果差值(i+1) - i是2,我放在dict_2,如果是3,我放在dict_3。我忽略了每个列表只有一个元素或者差异不是 2 或 3 的那些。

我正在尝试一种相当麻烦的方法:

def construct_dicts(init_dict, no_jumps=[2,3]):
    dct_2, dct_3 = {}, {}
    for key in init_dict.keys():
        for index in range(len(init_dict[key])):
            if init_dict[key][index+1] - init_dict[key][index] = no_jumps[0]:
                dct_2[key] = [index, index + 1]
            elif init_dict[key][index+1] - init_dict[key][index] = no_jumps[1]:
                dct_3[key] = [index, index + 1]

然而,这既麻烦又丑陋(目前还行不通)。有没有更pythonic的方法来做到这一点?

这是使用嵌套 collections.defaultdict:

的一般方法
def categorize_dicts(dictionary):
    dfd = defaultdict(defaultdict)
    for k, v in d.items():
        for i,j in zip(v, v[1:]):
            dfd[j-i].setdefault(k,[]).extend((i, j))
    return dfd  

演示:

In [28]: d = {'A': [0, 2, 5],
        ...:  'B': [1],
        ...:  'C': [3, 6, 9],
        ...:  'D': [4, 7, 10],
        ...:  'E': [8, 11, 13],
        ...:  'F': [12, 15, 17],
        ...:  'T': [19]}
        ...:  

In [29]: categorize_dicts(d)
Out[29]: 
defaultdict(collections.defaultdict,
            {2: defaultdict(None, {'A': [0, 2], 'E': [11, 13], 'F': [15, 17]}),
             3: defaultdict(None,
                         {'A': [2, 5],
                          'C': [3, 6, 6, 9],
                          'D': [4, 7, 7, 10],
                          'E': [8, 11],
                          'F': [12, 15]})})

您的代码中存在一些问题:

  1. for index in range(len(init_dict[key])) 结合 index + 1 最终会导致 IndexError.
  2. 您将索引 index + 1, index 放在新列表中,而不是相应的列表项。

此方法旨在解决上述问题并包括一些改进。它适用于任意差异并使用另一个 dict 来区分它们。值存储在 set 中,以防止具有相似差异的后续项目重复。如果这是无意的,那么可以使用 list 进行额外检查。

from collections import defaultdict

d = {
    'A': [0, 2, 5],
    'B': [1],
    'C': [3, 6, 9],
    'D': [4, 7, 10],
    'E': [8, 11, 13],
    'F': [12]
}
diff = defaultdict(lambda: defaultdict(set))

for k, v in d.items():
    for i, j in zip(v, v[1:]):
        diff[j-i][k] |= {i, j}