【问题标题】:How to split a python dictionary into multiple dictionaries based on values如何根据值将python字典拆分为多个字典
【发布时间】:2018-07-31 09:13:07
【问题描述】:

我有一本类似的字典:

{'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 的方式来做到这一点?

【问题讨论】:

  • 如果列表中的项目没有相同的差异怎么办?他们应该在一个单独的组中吗?
  • 如果差异既不是2也不是3,可以忽略。
  • 为什么是 2 或 3?这是问题的一部分吗?因为这里有很多可能性。请更具体。
  • 这是我的问题的一个受限部分。如果您想让它更通用,则构建与差异区间一样多的字典,而不仅仅是 2 或 3。这会更困难,但从长远来看也是有用的。
  • 您应该首先编写一个函数,该函数在给定[0, 2, 5] 时产生列表[0, 2][2, 5],在给定[1] 时不产生列表、在给定[3, 6, 9] 时产生[3, 6, 9] 等。

标签: python python-3.x dictionary ordereddictionary


【解决方案1】:

这是使用嵌套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]})})

【讨论】:

  • 我们不仅选择了完全相同的方法,而且变量名也完全相同=D
  • @a_guest 方法相似但不完全相同:))。
  • 对不起@a_guest,我必须选择 Kasramvd 的解决方案,因为他比你早了 3 分钟。非常感谢你们俩。
  • @Quubix 没问题 =D 但请注意,Kasramvd 的版本当前包含重复值,而不是您在 OP 中给出的示例(例如,6 因差异而重复 3 和键 'C' )。
【解决方案2】:

你的代码有几个问题:

  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}

【讨论】:

  • 一个问题,如果我还想要 2 和 3 以外的其他值,我该如何修改它,因为我不太了解它是如何工作的?
  • @Quubix 它将为每个差异创建一个dict,无需修改任何内容。最后,您可以选择您喜欢的任何差异,例如通过diff[2]diff[3]。请注意,它需要对原始字典中的值进行排序。
猜你喜欢
  • 2021-04-15
  • 1970-01-01
  • 2014-05-17
  • 2021-12-09
  • 2018-10-06
  • 2021-12-08
  • 2021-09-09
  • 2011-05-04
  • 2017-04-30
相关资源
最近更新 更多