如何用Python将一个字典根据 key 值拆分成多个字典?
现在有一个字典 a: a = { '0106': '50', '0117': '35', '0203': '30', '0205': '30', '3302': '45', '3305': '45' } 如何根据 key 值前面的两位数拆分成字典 b: b = { '01': { '0106': '50', '0117': '35', }, '02': { '0203': '30', '0205': '30', }, '33': { '3302': '45', '3305': '45', } }
请问大神用 python 代码如何优雅的实现?
如何用Python将一个字典根据 key 值拆分成多个字典?
collection defaultdict 了解一下
def split_dict_by_keys(original_dict, key_groups):
"""
根据指定的key分组将字典拆分为多个子字典
Args:
original_dict: 原始字典
key_groups: 包含多个key列表的列表,每个列表代表一个子字典需要的keys
Returns:
包含所有子字典的列表
"""
result = []
for keys in key_groups:
sub_dict = {k: original_dict[k] for k in keys if k in original_dict}
result.append(sub_dict)
return result
# 使用示例
data = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
groups = [['a', 'b'], ['c', 'd', 'e']]
split_dicts = split_dict_by_keys(data, groups)
print(split_dicts) # 输出: [{'a': 1, 'b': 2}, {'c': 3, 'd': 4, 'e': 5}]
# 如果某些key不存在,会自动跳过
groups2 = [['a', 'x'], ['b', 'c']] # 'x'不存在
split_dicts2 = split_dict_by_keys(data, groups2)
print(split_dicts2) # 输出: [{'a': 1}, {'b': 2, 'c': 3}]
这个函数的核心是字典推导式,遍历每个key组,只保留原始字典中存在的key。如果你想要更灵活的方式,比如按条件动态分组,可以这样:
def split_dict_by_condition(original_dict, condition_func):
"""
根据条件函数拆分字典
Args:
condition_func: 接收key和value的函数,返回分组标识
"""
from collections import defaultdict
result = defaultdict(dict)
for key, value in original_dict.items():
group_id = condition_func(key, value)
result[group_id][key] = value
return list(result.values())
# 示例:按key的类型分组
data = {'a': 1, 'b': 2, 'c1': 3, 'd2': 4}
split_by_type = split_dict_by_condition(data, lambda k, v: '字母' if k.isalpha() else '数字')
print(split_by_type) # [{'a': 1, 'b': 2}, {'c1': 3, 'd2': 4}]
用字典推导式按key分组最直接。
b={{}}
for key,value in a.items():
b[key[:2][key]]=value
>>> a = { ‘0106’: ‘50’, ‘0117’: ‘35’, ‘0203’: ‘30’, ‘0205’: ‘30’, ‘3302’: ‘45’, ‘3305’: ‘45’ }
>>> from itertools import groupby
>>> {k:dict(g) for k,g in groupby(sorted(a.items(), key=lambda x:x[0]), key=lambda x:x[0][:2])}
{‘01’: {‘0106’: ‘50’, ‘0117’: ‘35’}, ‘02’: {‘0203’: ‘30’, ‘0205’: ‘30’}, ‘33’: {‘3302’: ‘45’, ‘3305’: ‘45’}}
>>> a
{‘0117’: ‘35’, ‘0106’: ‘50’, ‘0205’: ‘30’, ‘0203’: ‘30’, ‘3305’: ‘45’, ‘3302’: ‘45’}
>>> {k[:2]: {i:j for i, j in a.items() if i.startswith(k[:2])} for k, _ in a.items()}
{‘02’: {‘0205’: ‘30’, ‘0203’: ‘30’}, ‘33’: {‘3305’: ‘45’, ‘3302’: ‘45’}, ‘01’: {‘0106’: ‘50’, ‘0117’: ‘35’}}
讲真写出来以后我并不觉得优雅:
>>> groupby_res = groupby(my_dict, lambda e: e[0:2])
>>>res = dict([(mini_key, dict([(key, my_dict[key]) for key in my_dict.keys() if key.startswith(mini_key)])) for mini_key, group in groupby_res for key in group])
>>> print(res)
>>> {‘01’: {‘0106’: ‘50’, ‘0117’: ‘35’}, ‘02’: {‘0203’: ‘30’, ‘0205’: ‘30’}, ‘33’: {‘3302’: ‘45’, ‘3305’: ‘45’}}
个人感觉最好还是写得明确一点,分多步构造也没关系。
from collections import defaultdict
ret = defaultdict(dict)
for k,v in a.items():
ret[k[:2]].update({k:v})
能写出来都是大神,至少我自己写不出来
from itertools import group_by
b = {k: dict(v) for k, v in groupby(list(a.items()), lambda item: item[0][:2])
from itertools import group_by
{k: dict(v) for k, v in groupby(a.items(), lambda item: item[0][:2])}
result = {}
for i in a:
if i[:2] not in result:
result[i[:2]] = {i : a[i]}
else:
result[i[:2]][i] = a[i]

