如何根据值将 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]})})
您的代码中存在一些问题:
for index in range(len(init_dict[key]))
结合 index + 1
最终会导致 IndexError
.
- 您将索引
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}
我有一本类似的字典:
{'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]})})
您的代码中存在一些问题:
for index in range(len(init_dict[key]))
结合index + 1
最终会导致IndexError
.- 您将索引
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}